Multiple PHP versions on a host using Docker
Often, PHP developers are faced with the task of testing the operation of a web application for several interpreter versions. It can be solved in different ways. You can tritely install different versions of PHP on one host, but this is fraught with library conflicts and other difficulties. The second extreme is to make several isolated virtual machines with different environments, but one cannot do without excessive use of hardware resources and wasting time on deploying the working environment. At the moment, this task can be solved most easily with the help of Docker.

Below, I will describe a working solution for Ubuntu 18, where the stack is Nginx + PHP-FPM. This solution is easily scaled: a container with PHP-FPM takes up only 300 MB in memory, and you can add containers with other versions of the interpreter with three commands (or, depending on preferences of even one, run). The second plus of this solution is that the developer does not need to switch the web server between interpreters, since they are already separated into different containers (the application code is used the same).
Addition: Judging by the comments, some readers did not understand for what cases the described solution is suitable. Therefore, I want to note that all of the following is intended to be used EXCLUSIVELY at the developer’s workstation, and may also be suitable for a stage server with some reservations.
So, let's begin…
As an example of creating a working environment, PHP versions 7.1 and 7.2 from the official Docker repository PHP are used . By analogy, if you have an image, you can install any version of PHP:
PHP-FPM by default runs on port 9000. When creating images, we published the 9000th container ports on the free 9071 and 9072 ports of the host machine (the numbers are taken arbitrarily from the unprivileged range). Next we will be proxying requests for PHP processing to these ports (the fastcgi_pass parameter in the Nginx virtual host configuration).
Also it was necessary to forward the directory with the projects (/ var / www) inside the containers, otherwise PHP-FPM swears that it does not see the files (if you know how to make this moment better / more correctly, then write in the comments).
We check that the containers are running, and the ports are published correctly:
Add the following lines to / etc / hosts:
Create a directory for the project:
I took the name for the project (project.local) and virtual hosts (project.local.php71 / 72) arbitrarily, but you can use names that are convenient for you (just remember to change the settings for virtual hosts).
Initially, only one phpinfo command was put in the index file, after setting up and verifying the system’s performance, index.php will need to be replaced with the one used in the project.
Create the file /etc/nginx/sites-available/project.local.php71 with the description of the first virtual host (it will be used to test the project under PHP v.7.1):
Similarly, the /etc/nginx/sites-available/project.local.php72 file for the second virtual host:
Now we make symlinks to the above configurations of virtual hosts and reboot Nginx:
As a result, we should get the PHP version (as a result of processing phpinfo commands by interpreters of different versions).
Now it only remains to upload your project to the /var/www/project.local folder and you can check its work in the PHP 7.1 interpreter at http: //project.local.php71 and PHP 7.2 at http: //project.local.php71 .
Additional Resources
1. The Complete Docker Practical Guide

Below, I will describe a working solution for Ubuntu 18, where the stack is Nginx + PHP-FPM. This solution is easily scaled: a container with PHP-FPM takes up only 300 MB in memory, and you can add containers with other versions of the interpreter with three commands (or, depending on preferences of even one, run). The second plus of this solution is that the developer does not need to switch the web server between interpreters, since they are already separated into different containers (the application code is used the same).
Addition: Judging by the comments, some readers did not understand for what cases the described solution is suitable. Therefore, I want to note that all of the following is intended to be used EXCLUSIVELY at the developer’s workstation, and may also be suitable for a stage server with some reservations.
So, let's begin…
1. Install Docker
sudo apt update
sudo apt install ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce
2. Install the containers with the necessary versions of PHP
As an example of creating a working environment, PHP versions 7.1 and 7.2 from the official Docker repository PHP are used . By analogy, if you have an image, you can install any version of PHP:
sudo docker pull php:7.1.25-fpm-stretch
sudo docker create --name=fpm71 -p 127.0.0.1:9071:9000 -v /var/www:/var/www php:7.1.25-fpm-stretch
sudo docker start fpm71
sudo docker pull php:7.2.13-fpm-stretch
sudo docker create --name=fpm72 -p 127.0.0.1:9072:9000 -v /var/www:/var/www php:7.2.13-fpm-stretch
sudo docker start fpm72
PHP-FPM by default runs on port 9000. When creating images, we published the 9000th container ports on the free 9071 and 9072 ports of the host machine (the numbers are taken arbitrarily from the unprivileged range). Next we will be proxying requests for PHP processing to these ports (the fastcgi_pass parameter in the Nginx virtual host configuration).
Also it was necessary to forward the directory with the projects (/ var / www) inside the containers, otherwise PHP-FPM swears that it does not see the files (if you know how to make this moment better / more correctly, then write in the comments).
We check that the containers are running, and the ports are published correctly:
sudo docker ps -a
sudo netstat -lpn
3. Configure the environment for virtual hosts
Add the following lines to / etc / hosts:
127.0.0.1 project.local.php71 ### php 7.1
127.0.0.1 project.local.php72 ### php 7.2
Create a directory for the project:
sudo mkdir -p /var/www/project.local
echo'<?php phpinfo(); ?>' | sudo tee /var/www/project.local/index.php
I took the name for the project (project.local) and virtual hosts (project.local.php71 / 72) arbitrarily, but you can use names that are convenient for you (just remember to change the settings for virtual hosts).
Initially, only one phpinfo command was put in the index file, after setting up and verifying the system’s performance, index.php will need to be replaced with the one used in the project.
4. Install nginx and configure virtual hosts
sudo apt install nginx
Create the file /etc/nginx/sites-available/project.local.php71 with the description of the first virtual host (it will be used to test the project under PHP v.7.1):
server {
listen 80;
server_name project.local.php71;
index index.php;
root /var/www/project.local;
location / {
try_files $uri$uri/ =404;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9071;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Similarly, the /etc/nginx/sites-available/project.local.php72 file for the second virtual host:
server {
listen 80;
server_name project.local.php72;
index index.php;
root /var/www/project.local;
location / {
try_files $uri$uri/ =404;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9072;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Now we make symlinks to the above configurations of virtual hosts and reboot Nginx:
cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/project.local.php71
sudo ln -s ../sites-available/project.local.php72
sudo systemctl reload nginx
5. Check
curl --silent http://project.local.php71/index.php | grep -o "PHP Version [0-9\.]\{1,\}"
curl --silent http://project.local.php72/index.php | grep -o "PHP Version [0-9\.]\{1,\}"
As a result, we should get the PHP version (as a result of processing phpinfo commands by interpreters of different versions).
Now it only remains to upload your project to the /var/www/project.local folder and you can check its work in the PHP 7.1 interpreter at http: //project.local.php71 and PHP 7.2 at http: //project.local.php71 .
Additional Resources
1. The Complete Docker Practical Guide