How to run multiple PHP versions with Apache on one Linux machine using Docker

I guess many PHP developers would love to have an easy way of switching between different versions of PHP on one machine. Or even having all required versions available in parallel.
Whether you work on multiple projects that require different versions of PHP or if you'd like to test a website on different PHP versions, it would be really nice to do this quickly without having to run multiple virtual machines or dealing with packages downgrade.
So, there's a really powerful tool that can be used to achieve this and its name is Docker.

Our goal was: elaborate a "magic command" that would run all local websites on multiple ports working on different versions of PHP, like so:
http://localsite runs with the currently installed PHP
http://localsite:8053 runs with PHP 5.3
http://localsite:8055 runs with PHP 5.5
http://localsite:8056 runs with PHP 5.6
http://localsite:8070 runs with PHP 7.0

Here's what you need to make it work like that.
Note that the instructions below are for Linux-based machines! Although you can run Docker on Windows and MacOS, the setup should be different.
1. Install docker.
If your computer runs Ubuntu, just follow this link installing Docker on Ubuntu.
You can find the instructions for other Linux distros there too.
2. Examine the following command:

sudo docker run -d -p 8055:80 -v /var/www:/var/www -v /etc/apache2/sites-available:/etc/apache2/sites-available -v /etc/apache2/sites-enabled:/etc/apache2/sites-enabled codeyourdream/apache-sendmail-php55

Here's what this command does.
a. It forwards your local /var/www, /etc/apache2/sites-available and /etc/apache2/sites-enabled to the corresponding folders of the Docker container. If your websites and/or apache configs are located in different folders, replace the first part of -v value.
I.e. the format is: docker run -v /host/directory:/container/directory -other -options image_name command_to_run
b. It runs the container from our image "codeyourdream/apache-sendmail-php55".

If you run this command, all your local sites should be available via port 8055, i.e. via URLs like http://localsite:8055

Some issues may appear on this step. Check the container logs for details.
Issues we faced in some situations: apache won't run inside the container, as local /etc/apache2/sites-enabled didn't have 000-default.conf. Easy to solve by creating that file with some dummy virtualhost.

3. You probably noticed that websites that use MySQL don't work, as they can't reach MySQL server.
That's easy to resolve.
3.1. Figure out the IP address of docker interface:
ifconfig docker0
Usually it's
3.2. Find your MySQL configuration (usually it's /etc/mysql/my.cnf) and replace bind-address with docker interface IP or (the latter will make MySQL listen to all available addresses).
3.3. In website database configs specify the IP of docker interface instead of "localhost".
3.4. Grant users the required database access permissions.
Here's an example for user "root" with password "password" and docker interface IP


That's it, the websites should be able to access the database now.

4. Finally, you may notice that the website can't send emails by standard PHP means (mail command).
In fact, that was the whole point of creating our own images - we added the support for sendmail.
To make it work you should run the following command:

sudo docker exec -it <docker container ID> /

You can find the docker container ID by running sudo docker ps

For our convenience we use bash scripts like this:

container=$(sudo docker run -d -p 8055:80 -v /var/www:/var/www -v /etc/apache2/sites-available:/etc/apache2/sites-available -v /etc/apache2/sites-enabled:/etc/apache2/sites-enabled codeyourdream/apache-sendmail-php55)
sudo docker exec -it $container /

If you encounter any issues, you should:
- check docker container logs: sudo docker logs <container ID>
- run bash in container and check what's going on there: sudo docker exec -it <container ID> /bin/bash

We'd be happy to help if you have any questions!

Add new comment

This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.