НейроАгент

Настройка портов для php5.6-fpm в Docker

Полное руководство по настройке портов для php5.6-fpm в Docker-контейнере и подключению к nginx. Узнайте, как запускать PHP 5.6 параллельно с PHP 7.4.

Вопрос

Настройка портов для php5.6-fpm в Docker-контейнере

Вопросы по конфигурации Docker-контейнера с PHP 5.6-FPM

Основная ситуация:

На сервере Ubuntu 20.04 работает связка nginx, php7.4-fpm, mariadb, symfony2. Необходимо перенести сайт с другого сервера (Ubuntu 14.04), где он работал на php5.6-fpm. Чтобы избежать переписывания функционала под новую версию PHP, выбран вариант запуска php5.6-fpm в Docker-контейнере.

Вопросы:

  1. Настройка портов для Docker-контейнера:
    Какие порты указывать для запуска php5.6-fpm из контейнера, чтобы его можно было подключить к nginx?

    Текущая команда:

    sudo docker container run -d --name php5.6-fpm -p ???:??? vicenterusso/php56-fpm
    

    Пример из документации образа:

    sudo docker container run --rm --name phpfpm -v $(pwd):/var/www/html -p 3000:3000 vicenterusso/php56-fpm php -S="0.0.0.0:3000" -t="/var/www/html"
    
  2. Конфигурация nginx для подключения к контейнеру:
    В настройках nginx-конфига сайта нужно указать, к какому сокету привязаться для контейнерного php-fpm. Текущая настройка:

    fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    

    Что нужно изменить для подключения к php5.6-fpm в Docker-контейнере?

  3. Параллельная работа PHP-версий:
    Будет ли контейнер с php5.6-fpm работать параллельно с php7.4-fpm на хосте? Можно ли подключать к php5.6-fpm любые сайты, и нужно ли в URL указывать номера портов?

НейроАгент

Для настройки php5.6-fpm в Docker-контейнере и подключения к nginx используйте следующие параметры:

  1. Основной порт для php5.6-fpm - 9000. По умолчанию PHP-FPM слушает на порту 9000, поэтому для подключения контейнера к nginx необходимо указать этот порт. Для вашей команды:
bash
sudo docker container run -d --name php5.6-fpm -p 127.0.0.1:9999:9000 vicenterusso/php56-fpm

здесь 9999 - хост-порт, который вы можете выбрать свободным, а 9000 - порт внутри контейнера.

  1. Конфигурация nginx должна быть изменена с unix-сокета на TCP-соединение:
nginx
fastcgi_pass 127.0.0.1:9999;

Или, если используете docker-compose с сетью:

nginx
fastcgi_pass php-fpm:9000;
  1. Параллельная работа PHP-версий возможна без проблем. Контейнер с php5.6-fpm будет работать независимо от хостовой системы с php7.4-fpm. Для подключения сайтов к php5.6-fpm необходимо:
  • В конфиге nginx указать правильный порт
  • При необходимости можно настроить разные виртуальные хосты для разных PHP-версий
  • В URL не нужно указывать номера портов, если используете стандартные порты 80/443

Содержание


Базовая конфигурация портов для php5.6-fpm

PHP-FPM по умолчанию слушает на порту 9000, как указано в документации PHP. Для Docker-контейнера с php5.6-fpm необходимо правильно настроить проброс портов.

Стандартная команда запуска:

bash
sudo docker container run -d --name php5.6-fpm \
  -p 127.0.0.1:9999:9000 \
  -v /path/to/your/project:/var/www/html \
  vicenterusso/php56-fpm

Пояснение:

  • 127.0.0.1:9999:9000 - пробрасываем порт 9000 из контейнера на хост-порт 9999 только на localhost
  • vicenterusso/php56-fpm - образ с PHP 5.6-FPM
  • -v /path/to/your/project:/var/www/html - монтируем проект в контейнер

Альтернативный вариант с TCP-соединением:

Если вы хотите, чтобы nginx мог подключаться к php-fpm через Docker-сеть:

bash
sudo docker container run -d --name php5.6-fpm \
  --network my-app-network \
  -p 9000:9000 \
  vicenterusso/php56-fpm

Настройка nginx для подключения к Docker-контейнеру

Для подключения nginx к php5.6-fpm в Docker-контейнере необходимо изменить конфигурацию fastcgi_pass.

Вариант 1: Через TCP-порт (рекомендуемый)

nginx
server {
    listen 80;
    server_name your-domain.com;
    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9999;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

Вариант 2: Через Docker-сеть

Если используете docker-compose с общей сетью:

nginx
location ~ \.php$ {
    fastcgi_pass php5.6-fpm:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Вариант 3: Через Unix-сокет (более сложный)

Для использования unix-сокетов необходимо смонтировать общий том между контейнерами:

yaml
# docker-compose.yml
version: '3.4'
services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./php5.6-fpm.sock:/var/run/php5.6-fpm.sock
    depends_on:
      - php5.6-fpm

  php5.6-fpm:
    image: vicenterusso/php56-fpm
    volumes:
      - ./php5.6-fpm.sock:/var/run/php5.6-fpm.sock
nginx
# nginx.conf
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5.6-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Параллельная работа PHP-версий

Да, контейнер с php5.6-fpm будет работать параллельно с php7.4-fpm на хостовой системе без конфликтов.

Как это работает:

  1. Изоляция процессов: Docker-контейнер изолирован от хостовой системы, поэтому PHP-версии не конфликтуют
  2. Разные порты: Используются разные порты для подключения (9000 для php7.4-fpm на хосте, 9999 для php5.6-fpm в контейнере)
  3. Разные конфиги: nginx может иметь разные location-блоки для разных PHP-версий

Пример конфигурации для нескольких PHP-версий:

nginx
# Сайт с PHP 7.4 (хостовая система)
server {
    listen 80;
    server_name site1.com;
    root /var/www/site1;
    
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

# Сайт с PHP 5.6 (Docker-контейнер)
server {
    listen 80;
    server_name site2.com;
    root /var/www/site2;
    
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9999;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

URL-адреса:

В URL не нужно указывать номера портов, если используете стандартные порты 80/443. Номера портов указываются только в конфигурации nginx для внутреннего подключения к php-fpm.


Примеры docker-compose конфигураций

Простой пример с TCP-портом:

yaml
version: '3.4'
services:
  nginx:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./project:/var/www/html
    depends_on:
      - php5.6-fpm

  php5.6-fpm:
    image: vicenterusso/php56-fpm
    ports:
      - "127.0.0.1:9999:9000"
    volumes:
      - ./project:/var/www/html
nginx
# nginx.conf
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        server_name localhost;
        root /var/www/html;
        index index.php index.html;

        location / {
            try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php$ {
            fastcgi_pass 127.0.0.1:9999;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}

Пример с Docker-сетью:

yaml
version: '3.4'
services:
  nginx:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./project:/var/www/html
    networks:
      - app-network

  php5.6-fpm:
    image: vicenterusso/php56-fpm
    volumes:
      - ./project:/var/www/html
    networks:
      - app-network

networks:
  app-network:
    driver: bridge
nginx
# nginx.conf с использованием Docker-сети
location ~ \.php$ {
    fastcgi_pass php5.6-fpm:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Устранение распространенных проблем

Проблема 1: Connection refused

Ошибка: connect() failed (111: Connection refused) while connecting to upstream

Решение:

  • Проверьте, что контейнер запущен: docker ps
  • Убедитесь, что порт правильно проброшен
  • Проверьте firewall: sudo ufw status

Проблема 2: Permission denied для сокета

Ошибка: Permission denied при работе с unix-сокетом

Решение:

  • Убедитесь, что nginx и php-fpm используют одного пользователя
  • Или используйте TCP-соединение вместо сокета

Проблема 3: PHP-FPM не стартует

Решение:

  • Проверьте логи: docker logs php5.6-fpm
  • Убедитесь, что конфиг php-fpm корректен
  • Проверьте права на монтируемые тома

Проблема 4: Несовместимость расширений

Решение:

  • Для PHP 5.6 некоторые расширения могут быть недоступны
  • Используйте Alpine-версии образов для меньшего размера
  • Собирайте кастомный Dockerfile с нужными расширениями

Источники

  1. Stack Overflow - How to correctly link php-fpm and Nginx Docker containers
  2. Medium - Setting up nginx and PHP-FPM in Docker with Unix Sockets
  3. pascallandau.com - PHP, PHP-FPM and NGINX on Docker
  4. Stack Overflow - How to connect nginx to php-fpm using unix socket in docker
  5. GitHub - eustatos/docker-nginx-php-fpm-socket-tcp
  6. inanzzz - Using unix socket for php-fpm and nginx docker setup

Заключение

  1. Основной порт для php5.6-fpm - 9000, его нужно пробросить на хост-порт (например, 9999) с помощью параметра -p 127.0.0.1:9999:9000

  2. Конфигурация nginx должна использовать fastcgi_pass 127.0.0.1:9999; вместо unix-сокета для подключения к контейнеру

  3. Параллельная работа PHP-версий полностью возможна - контейнер изолирован от хостовой системы, и номера портов в URL не требуются

  4. Рекомендуемый подход - использовать TCP-соединение через проброшенный порт, так как это проще настраивать и отлаживать

  5. Для продакшена рассмотрите использование docker-compose с общей сетью между контейнерами nginx и php-fpm