LEMP : Nginx php-fpm mariadb with docker compose


docker compose

Dockerising, a LEMP stack ( Nginx Php-fpm and Mariadb ) with docker-compose on Linux . Please check out this post to see how the same can be done with docker command line .


Installation of docker-compose is covered in detail on official site,  do read through it . Pasting the quick howto  for debian here.

sudo apt-get install python-pip
sudo pip install --upgrade pip
sudo pip install docker-compose

Howto ::

  1. If you are following the last post you should now have the directory structure and conf files as below
    |-- mariadb
    | |-- data
    | | |-- ...
    | | `-- ...
    |-- nginx
    | |-- certs
    | |-- conf.d
    | | `-- techblog.com
    | |-- files
    | | |-- ...
    | | `-- ...
    | |-- log
    | | |-- ...
    | | `-- ...
    `-- phpfpm 
     |-- Dockerfile 
  2. Create  docker-compose.yml
    Create the docker-compose.yml file as below

    version: '3'
     image: mariadb:latest
     - ./mariadb/data:/var/lib/mysql
     - .env
     build: ./phpfpm/
     - ./nginx/files:/home/tech
     image: nginx:alpine
     - ./nginx/conf.d:/etc/nginx/conf.d 
     - ./nginx/certs:/etc/nginx/certs 
     - ./nginx/log:/var/log/nginx
     - ./nginx/files:/home/tech
     - 80:80
     - 443:443

    First line mentions the version of docker-compose syntax we are using. The later lines mentions the services and options they use, you can cross-reference them with the  docker commands used in the first post

  3. Make the LEMP stack online.
    docker-compose up -d 

    Above command will bring the 3 services mariadb, phpfpm and nginx online by deploying the respective  containers . Phpfpm container will be deployed after building the image with Dockerfile, rest of the services will be containerised from the base images. A bridge network will be auto created by the docker-compose and all the services will be added to it so that they can talk to each other.

  4. Monitoring/ Troubleshooting
    docker-compose ps 
    docker-compose top
    docker-compose logs
  5. Making the stack offline
    docker-compose down

LEMP : Nginx php-fpm mariadb with docker

docker commandlineOverview::

Dockerising, a LEMP stack ( Nginx Php-fpm and Mariadb ) with command line on Linux . As a real world example we’ll be restoring a wordpress site to this stack .


Installation of docker is covered in detail on official site, please do read through it . Pasting the quick howto  for debian here.

sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg2 \

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \

sudo apt-get install docker-ce

Howto ::

  1. Create the directory structure as below  /root/lemp/
    |-- mariadb
    | |-- data
    |-- nginx
    | |-- certs
    | |-- conf.d
    | |-- files
    | `-- log
    `-- phpfpm
  2. Create a network
    Below command creates a docker bridge network named internal

    docker create network internal
  3. Deploy Mariadb container .
    docker run --name mariadb --network=internal -v /root/lemp/mariadb/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=your_secret_pass  -d mariadb:latest

    Above command will, download the latest mariadb image.
    run : Run it with the name mariadb.
    -v : Create a volume mount for /var/lib/mysql to host dir /root/lemp/mariadb/data.
    -e :Pass the mysql root password as environment variable.
    —network : Attach the container to bridge network internal.
    -d :Detach  and run the container in background.

  4. Create DB/grant privileges/restore database
    docker exec -i mariadb mysql -uroot -pyour_secret_pass -e "create database tech_blog"
    docker exec -i mariadb mysql -uroot -pyour_secret_pass -e "GRANT ALL PRIVILEGES ON techie_blog.* TO 'techie_user'@'%' identified by 'your_db_pass'"
    docker exec -i mariadb mysql -uroot -pyour_secret_pass --force tech_blog < mariadb/tech_blog.sql

    exec -i : executes commands interactively in a running container

  5. Enable mysqli support on php-fpm.
    As we are hosting a WP site on this stack we need to have mysqli support enabled for php-fpm, this can be achieved by creating a new image with mysqli support

    cd /root/phpfpm
    vi  Dockerfile

    FROM php:fpm-alpine
    RUN docker-php-ext-install mysqli

    docker build -t php_fpm .

    build -t : builds a new image and tags it as php_fpm:latest

  6. Deploy Php-fpm
    docker run -d --name phpfpm --network=internal -v /root/lemp/nginx/files:/home/tech  -v /root/lemp/phpfpm/php-fpm.d:/etc/php-fpm.d/  php_fpm:latest 
  7. Configure nginx
    Copy the WP site nginx conf file to /root/lemp/nginx/conf.d/techblog.com

    cat /root/lemp/nginx/conf.d/techblog.com

    server {
    listen 80;
    server_name techblog.com;
    root /home/tech ;
    access_log /var/log/nginx/techblog.com;
    index index.php index.html index.htm;
    location / {
    try_files $uri $uri/ /index.php$args;
    }error_page 404 /404.html;error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /home/tech;

    # pass the PHP scripts to FastCGI server listening on the php-fpm socket
    location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass phpfpm:9000;
    fastcgi_index index.php;
    fastcgi_split_path_info ^(/)(/.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;


  8. WP file copy/configure
    Copy the WP files to /root/lemp/nginx/files
    Change database host configuration in the wp-config.php as below to point it to the Mariadb container

    define(‘DB_HOST’, ‘mariadb’);

  9. Deploy Nginx container
    docker run -d -p 80:80 --name nginx --network=internal -v /root/lamp/nginx/conf.d:/etc/nginx/conf.d -v /root/lamp/nginx/certs:/etc/nginx/certs -v /root/lamp/nginx/log:/var/log/nginx -v /home/tech:/home/tech nginx:alpine

    -p : exposes the nginx port 80 of container and binds it to port 80 on the host.


docker ps  # Shows the running containers
docker logs <container_id> # shows the container logs
docker inspect <container_id>