Несколько версий PHP на хосте с помощью Docker

в 11:49, , рубрики: docker, nginx, php, виртуализация, системное администрирование

Часто перед разработчиками PHP встаёт задача проверить работу веб-приложения под несколько версий интерпретатора. Решить её можно разными способами. Можно банально установить разные версии PHP на один хост, но это чревато конфликтами библиотек и другими сложностями. Вторая крайность — сделать несколько изолированных виртуальных машин с разным окружением, но здесь не обойтись без чрезмерного использования аппаратных ресурсов и излишней траты времени на разворачивание рабочего окружения. На настоящий момент наиболее просто решить данную задачу можно с помощью Docker.

image

Ниже я опишу рабочее решение под Ubuntu 18, где в качестве стека используется связка Nginx + PHP-FPM. Данное решение легко масштабируется: контейнер с PHP-FPM занимает всего 300 Мб в памяти, а добавить контейнеры с другими версиями интерпретатора можно тремя командами (или в зависимости от предпочтений даже одной — run). Второй плюс этого решения в том, что разработчику не нужно переключать веб-сервер между интерпретаторами, так как они уже разнесены в разные контейнеры (код приложения при этом используется один и тот же).

Итак, начнём…

1. Устанавливаем 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. Устанавливаем контейнеры с нужными версиями PHP

В качестве примера создания рабочего окружения использованы PHP версий 7.1 и 7.2 из официального Docker-репозитория PHP. По аналогии при наличии образа можно установить какие угодно версии 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 по умолчанию работает на 9000 порту. При создании образов мы опубликовали 9000-е порты контейнеров на свободные 9071 и 9072 порты хост-машины (номера взяты произвольно из непривилегированного диапазона). Далее на эти порты мы будем проксировать запросы на обработку PHP (параметр fastcgi_pass в конфигурации виртуальных хостов Nginx).

Также понадобилось пробросить внутрь контейнеров каталог с проектами (/var/www), иначе PHP-FPM ругается, что не видит файлов (если знаете, как сделать этот момент лучше/правильней, то пишите в комментарии).

Проверяем, что контейнеры запущены, а порты опубликованы правильно:

sudo docker ps -a

sudo netstat -lpn

3. Настраиваем окружение для виртуальных хостов

Добавляем в /etc/hosts строки:

127.0.0.1    project.local.php71  ### php 7.1
127.0.0.1    project.local.php72  ### php 7.2

Создаём каталог для проекта:

sudo mkdir -p /var/www/project.local

echo '<?php phpinfo(); ?>' | sudo tee /var/www/project.local/index.php

Название для проекта (project.local) и виртуальных хостов (project.local.php71/72) я взял произвольно, но вы можете использовать удобные для вас названия (только не забудьте при этом поменять настройки виртуальных хостов).

Изначально в индексный файл была положена только одна команда phpinfo, после настройки и проверки работоспособности системы, index.php нужно будет заменить на тот, что используется в проекте.

4. Устанавливаем nginx и настраиваем виртуальные хосты

sudo apt install nginx

Создаём файл /etc/nginx/sites-available/project.local.php71 с описанием первого виртуального хоста (он будет использоваться для проверки работы проекта под 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;
  }
}

Точно так же файл /etc/nginx/sites-available/project.local.php72 для второго виртуального хоста:

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;
  }
}

Теперь делаем симлинки на вышесозданные конфигурации виртуальных хостов и перегружаем 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. Проверяем

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,}"

В качестве результата мы должны получить версию PHP (как результат обработки команды phpinfo интерпретаторами разных версий).

Теперь осталось лишь залить свой проект в папку /var/www/project.local и можно проверять его работу в интерпретаторе PHP 7.1 по адресу http://project.local.php71 и PHP 7.2 по http://project.local.php71.

Дополнительные материалы
1. Полное практическое руководство по Docker

Автор: o-pod

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js