A universal Docker Compose development environment setup


Ever since I started programming, I've used many different tools to manage local development environments. First it was WAMP on Windows and MAMP on MAC. Both of these were fine if I was working on a small project that didn't require too much customisation in terms of installed PHP, Apache and its modules. But as soon as I started working on projects that required complex server configuration, things started breaking and going wrong. So, if you're facing a similar situation, how do you resolve it?

One way is by using Vagrant. This helps to create virtual machines with unique combinations of software. The software is configured to each project you are working on and you can share these virtual machines with your team. The main disadvantage of this approach is the overall Vagrant performance and the size of the virtual machines. Each project has to run full virtual machines, which can lead to high CPU, memory and disk space consumption. 

Docker is a much better solution to the problem. It allows you to package up an application with all of its dependencies into a container, which is like a lightweight virtual machine. You can use multiple Docker images, which are available on Docker Hub and link them together. This allows you to test multiple configurations, without the risk of breaking your existing projects! If something goes wrong, you simply rebuild the project, which doesn't take long. Afterwards, you'll be left with a perfect configuration that you can share with your team and you can even use it in the production environment.

Take a look at the details below for more information on our Docker configuration. 


You need to have Docker with Docker Compose installed on your system. You can do it with the installer available in here: However, I don't recommend approaching it this way because it mounts shared volumes using vboxsf mode, which is very slow. As an alternative you can use the Vagrant box available here:


Clone this repository:

$ git clone

Then enter the project folder and run:

$ docker-compose up

If you use the Vagrant box, visit this IP address:

If you are using a Docker machine, check the machine IP with command:

$ docker-machine ip default

If everything is set up correctly you should see phpinfo() output

What containers are included?


Nginx is used as a load balancer/reverse proxy server. The whole www directory is mounted to it.

You can access nginx logs in the following directories on your host machine:

  • logs/nginx

In order to run multiple websites you need to add an individual host for each one of them inside the host's file. For example, on Mac edit /etc/hosts and add:

Each time you want to run a new website you need to add a new server block inside the site's enabled directory. Sample configuration files are provided inside the site examples directory. Things to modify inside the nginx server block configuration:

server_name; # One of vhost added to /etc/hosts file. Needs to be unique for each project
root /var/www/drupal7; # Path to website inside www directory

If you are using custom PHP-FPM container you also need to change fastcgi_pass. For example this is the default one:

fastcgi_pass php:9000;

If your PHP container name is my-php fastcgi_pass change it to this:

fastcgi_pass my-php:9000;



Default PHP-FPM container. If you don't need a custom PHP version/settings you can use this container to run all of your apps.

If for some projects you want custom PHP settings, clone this container (php.ini is available in conf folder). If you need additional Linux packages, install them inside Dockerfile.

After you have cloned the PHP container you can modify docker-compose.yml for example.

    build: my-php-fpm
        - 9002:9000 # Remember to have unique host port number
      - mysql:mysql
        - ./www:/var/www

    build: nginx
        - 80:80
        - php
        - symfony
        - myphp # After new container is created you need to link it to nginx
        - symfony
        - ./www:/var/www
        - ./sites-enabled:/etc/nginx/sites-enabled
        - ./logs/nginx/:/var/log/nginx



MySQL database container. MySQL container has the following shared volumes:

  • dbstorage: Prevent from data loss when destroying container

  • db: You can place databases on your host and then import them from inside the container using this command:

$ docker exec -it dockeruniversal_mysql_1 /bin/bash
$ mysql -u root -p password database_name < database_file.sql



You can use this container to run Symfony2 or Symfony3 apps. Used as an example and can be disabled.



Used to access MYSQL data with phpmyadmin on port 8181 for example You can disable this if you want.


Andrzej Kogut
  • docker
  • guide
  • tutorial
  • git

Get in Touch