Docker tutorial Learn how to create Docker container with PHP 5.6 and Apache server

Scroll this

In this tutorial you will learn how to create Docker container (based on CentOS) with PHP 5.6 and Apache web server using supervisor service. PHP code will be run from the host machine. This setup is useful if you need to support legacy PHP application and you don’t want to pollute host machine with another parallel PHP installation.  Of course, XDebug will be configured as well.



All config files are available from github:


1. Create new directory, for example centos-apache-php56.

$ mkdir centos-apache-php56

$ cd centos-apache-php56

2. Clone config files from github:

$ git clone


$ git clone

3. Review config files

Or just skip to the next step. 🙂


Docker file is a text file containing instructions to Docker  how to build an image. For very simple images – Dockerfile is the only configuration file needed.

  • FROM – tells docker on which existing image our image will be based. I used CentOS.
  • USER – which user to use for running the image and for any RUN, CMD and ENTRYPOINT instruction.
  • LABEL maintainer – replacement for now deprecated MAINTAINER instruction
  • RUN – execute commands, creates new layer based on the previous layer. In this case we use it to install additional packages like apache web server, php56 and supervisor daemon.
  • COPY – copies files from host system to the container
  • EXPOSE – on which ports Docker container will listen during runtime. In this case we will connect to the apache in the Docker container, from the host system, on the port 8080.
  • CMD – which command will be executed when the container is run. In this case supervisord is executed since we are running 2 services (apache and php56-fpm) in one container.

So, basically, building the Docker container is very easy. Just select the base image, and run commands to install or configure the container in very similar way you would do if you were installing GNU/Linux distribution on your server or desktop. You can find appropriate image by running:

$ docker search centos

Which will display various images based on centos. Or explore:


It is recommended to have one service per container, but in this example it makes sense to have two services, Apache web server and php56-fpm. Running PHP as FPM (FastCGI Process Manager) has performance benefits, enable us to have more PHP versions installed on the system (if we desire so) and for some distributions (Fedora) older versions of PHP are available only as FPM.

Supervisor enables us to start two (or more) services when the container is started,

For more info visit

Configuring Apache and PHP-FPM

Next step is to configure Apache and PHP-FPM and it is done in the same way as you would do on “ordinary” GNU/Linux distribution. You can find very nice instructions here:


Tell Apache that it should use PHP-FPM:


Configure PHP-FPM to use sockets. Copy existing config file (/opt/remi/php56/root/etc/php-fpm.d/www.conf) and change/set this options:

View complete file: www.conf.


In this case XDebug will auto start every time – just to make things simple for this tutorial.

4. Build the image

$ sudo docker build -t centos7-apache-php56-fpm .

(don’t forget the dot and the end of line)

5. Create test php 5.6 script. For example mine is in /srv/php56test/ .

6. Run Docker

$ sudo docker run -dp 8080:80 -v /srv/php56test/:/var/www/html/ centos7-apache-php56-fpm

(replace /srv/php56test/ with path to your test script on the host machine)


  • -d starts docker container in the background
  • -p maps host port 8080 to port 80 (inside container, Apache is listening on the port 80)
  • -v files on the host system at the location /srv/php56test/ will be accessed in the container at the location /var/www/html/

7. Test

Visit http://localhost:8080 with the browser.

Configuring PhpStorm to work with XDebug

  • Don’t change Settings : Languages & Frameworks : Debug : DBGp Proxy
  • In the top right corner where debug controls are, select “Edit configurations …”.
  • Click on the “Add new configuration” plus button and select “PHP Remote Debug”.
  • In the name field enter whatever makes sense for you.
  • Check the “Filter debug connection by IDE key. For IDE key enter “docker”, since this is the key I choose in the docker image config files.
  • Click on the 3 dots in the “Server:” line above.
  • Type any name, enter “localhost” for host, “8080” for the port. Debugger is XDebug.
  • In my case path on the host machine is /srv/php56test/ . Next to it, in the column “Absolute path on the server” enter /var/www/html/ . Click “Ok”.
  • For server select the server you just created. Click “Apply” and “Ok”.
  • Put the breakpoint on the echo line in index.php. Make sure that PhpStorm is listening for the PHP Debug connection (headphone, top-right).
  • Reload the localhost:8080 .

Cheat sheet

$ sudo docker pull <IMAGE NAME>
Get an image from the repository.

$ sudo docker images
List of top level images, you should see at least centos7-apache-php56-fpm.

$ sudo docker rmi <IMAGE ID>
Remove the image.

$ sudo docker ps
List of running containers.

$ sudo docker exec -it <CONTAINER ID> bash
Run a command in the running container.  In this case it will run bash – which means we can “get inside” of container and execute commands in the shell running in the container.

$ sudo docker top <CONTAINER ID>
Display the running processes of a container

$ sudo docker stop <CONTAINER ID>
Stops the container in more graceful way then the kill command. Stop will first send SIGTERM and the SIGKILL to the processes in the container.

$ sudo docker start <CONTAINER ID>
Starts one or more previously stopped containers.

$ sudo docker kill <CONTAINER ID>
Kill running container. Kill will just send SIGKILL signal. (Think of it like unix cmd kill -9 <pid>).

$ ls -al /var/lib/docker
Usual place where containers and other Docker files are stored. To change the location check the –graph option.

$ sudo docker login –username=<username>
Login to Docker registry with the same credentials you used to register on

$ sudo docker push <IMAGE NAME>
Push image to the registry.



Submit a comment