Docker development environment for Magento

It has never been easier to create a development environment. No meter what operation system you use with Docker you can build the exact configuration you need. In this post we will provide steps for creating a sample Magento development environment configured in a single docker-compose.yml file.

Docker is an open source container technology that allows to run any Linux based application as a lightweight container. Docker Compose is a tool for running multi-container Docker applications, which are defined in the Compose file (docker-compose.yml).

If you haven’t installed Docker yet go ahead and download it from their site. There is a native Docker application now for Mac OS, just run the installer. For Ubuntu you can use these instructions to get the latest Docker and Docker Compose installed.

As for any PHP web application, for Magento development environment we need a WEB server, a database server and PHP. Any of those services can be run as a Docker container. There are official images on Docker Hub and we will use them to start our containers.

Lets begin with creating a docker-compose.yml file. There are two versions of the Compose file format. As we use version 2 we place the following line to file:

version: '2'

There are 3 key elements that we can define in the Compose file: services, networks and volumes. These will be 3 services in our case: nginx, php, db. For each service an image or a build (in case we build our own image) should be specified. Our Nginx service will be based on the official image from Docker Hub. Then we declare ports to be exposed in (HOST:CONTAINER) format. In our case we will access web server via 8880 port. Also we need to declare volumes – paths that will be mounted from the host to container (HOST:CONTAINER). So here is how the declaration of Nginx service looks like:

version: '2'
services:
  nginx:
    image: nginx:latest
    ports:
     - "8880:80"
    volumes:
     - ./source:/source
     - ./nginx.conf:/etc/nginx/conf.d/default.conf

In the lines above we assume that we place Magento files into the source directory. In Nginx config nginx.conf we specify source directory as root. This configuration file will be mounted to /etc/nginx/conf.d/default.conf in container’s filesystem. So here is its content (nginx.conf):

server {
    index index.php index.html;
    server_name localhost;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /source;

    location / {  
        try_files $uri $uri/ @handler;  
    }  

    location @handler { 
        rewrite / /index.php;  
    }  
    
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Our first container is ready. Next one is PHP. Unfortunately, we cannot use the official image here because Magento requires some extra PHP extensions like mcrypt, soap etc. So we will build our own custom PHP image. Special Dockerfile file is used for doing that. So create a php subfolder with the file named Dockerfile:

FROM php:5.6-fpm

RUN apt-get -qq update && apt-get -qq install libxml++2.6-dev > /dev/null
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng12-dev \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd mbstring mysql mysqli pdo pdo_mysql soap
    
RUN apt-get install -y libmcrypt-dev
RUN docker-php-ext-install mcrypt

RUN apt-get install -y libicu-dev
RUN pecl install intl
RUN docker-php-ext-install intl

The first line says that this image is based on the official PHP FPM image, with next commands we install the required extensions.

It’s time to return to the docker-compose.yml file and add the PHP service:

php:
    build: ./php    
    volumes:
     - ./source:/source

This time instead of image directive we’ve used build and specified the path to the directory that contains Dockerfile That is it, on docker-compose up command PHP image will be built automatically.

The last container is for the database server. Lets use MariaDB image for it:

db:
    image: mariadb:latest
    environment:
      MYSQL_DATABASE: 'magento'
      MYSQL_USER: 'magento'
      MYSQL_PASSWORD: 'magento'
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'

Note that we used some environment variables here to define database name, user and password.

You may ask how those containers will communicate to each other. The cool thing is that on docker-compose up a virtual network will be created and it will link our services so containers will be reachable at the hostname identical to service names specified. That is why in Nginx config we set the address to PHP-FPM like this:

fastcgi_pass php:9000;

We are done with docker-compose.yml. Lets try to run everything:

sudo docker-compose up

Hopefully you can navigate now to http://127.0.0.1:8880/ and see a Magento installation wizard.
Magento_Installation_Wizard

That’s it. Files are available on GitHub. We highly recommend to read the official documentation to find out all Docker features. Good luck.

Read more – Reset an administrator password or add a Magento admin user using MySQL