Гид по технологиям

Docker для PHP с Apache — руководство по контейнеризации

6 min read DevOps Обновлено 18 Dec 2025
Docker для PHP с Apache — быстрое руководство
Docker для PHP с Apache — быстрое руководство

Кратко

Контейнеризация PHP‑приложения с Apache даёт переносимость и воспроизводимость окружения: создайте Dockerfile на базе официального образа php:8.0-apache, добавьте нужные расширения и конфигурации, используйте multi‑stage build для Composer и управляйте стартовой логикой через собственный скрипт запуска. В статье — пошаговые примеры, чек‑листы и рекомендации по отладке.

Быстрая навигация

  • Создание Dockerfile
  • Настройка Apache
  • Добавление расширений PHP
  • Конфигурация PHP
  • Использование Composer
  • Пользовательские скрипты запуска
  • Когда это не подходит и альтернативы
  • Чек‑листы и критерии приёмки

Логотип Docker: контейнеризация PHP с Apache

Docker-контейнеры делают приложение переносимым между окружениями. Как только образ готов, вы можете запускать приложение везде, где есть Docker. Ниже — практическое руководство по контейнеризации PHP‑веб‑приложения с Apache на официальном образе PHP.

Важно: официальные образы php с вариациями apache уже включают конфигурацию веб‑сервера, поэтому ручная установка Apache обычно не требуется. Образы также содержат утилиты для управления расширениями PHP.

Создание Dockerfile

Docker‑образ строится из файла Dockerfile, содержащего набор инструкций, которые выполняет сборщик. Частые инструкции:

  • COPY — копирует файлы и каталоги в контейнер.
  • RUN — выполняет команду внутри контейнера.

Простейший пример: скопировать файлы сайта в образ на базе php:8.0-apache и открыть порт 80.

FROM php:8.0-apache
WORKDIR /var/www/html

COPY index.php index.php
COPY src/ src
EXPOSE 80

Этот Dockerfile берёт index.php и папку src из вашей рабочей директории и помещает их в документ‑рут Apache. После сборки образа и запуска контейнера вы увидите сайт, обслуживаемый Apache.

Пример команд сборки/запуска:

docker build -t my-php-site:latest .
docker run -d -p 80:80 my-php-site:latest

Пояснения:

  • Документ‑рут по умолчанию в образах php на Debian — /var/www/html.
  • WORKDIR задаёт рабочую директорию для последующих инструкций.
  • EXPOSE отмечает, что контейнер слушает порт 80; при запуске с -P Docker может автоматически пробросить случайный порт хоста.

Рекомендации по структуре проекта

  • Держите Dockerfile в корне проекта.
  • Игнорируйте в .dockerignore временные папки, vendor и node_modules для уменьшения контекста.
  • Не храните секреты в образе; используйте переменные окружения или секреты Docker.

Настройка Apache

Образы php:*-apache основаны на Debian — и вы можете устанавливать дополнительные пакеты через apt.

Утилиты Apache (a2enmod, a2dismod, a2ensite, a2dissite) доступны и позволяют включать/отключать модули и сайты. Основной конфигурационный файл Apache: /etc/apache2/apache2.conf.

Одно из полезных изменений — явно указать ServerName, чтобы убрать предупреждение “unable to reliably determine ServerName” в логах контейнера.

Добавьте собственный виртуальный хост для настройки, превышающей стандартный 000-default.

COPY my-apache-site.conf /etc/apache2/sites-available/my-apache-site.conf

RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf &&
    a2enmod rewrite &&
    a2dissite 000-default &&
    a2ensite my-apache-site &&
    service apache2 restart

Пояснения:

  • В примере мы отключаем стандартный сайт, включаем кастомный и модуль mod_rewrite.
  • Возможно, потребуется включить модуль headers, если вы работаете с заголовками ответа.

Важно: в контейнере команды вроде service apache2 restart могут работать, но для финальной сборки и запуска логичнее перезапускать процесс при запуске контейнера (см. раздел про скрипты запуска).

Добавление расширений PHP

Образы PHP содержат утилиты для установки расширений. Список текущих расширений можно посмотреть, запустив php -m внутри работающего контейнера.

Часто используемые расширения устанавливаются через docker-php-ext-install:

docker-php-ext-install pdo_mysql

Некоторым расширениям требуется предварительная конфигурация:

RUN docker-php-ext-configure gd --with-jpeg=/usr/include/ &&
    docker-php-ext-install gd

PECL‑расширения устанавливаются в два шага: сначала pecl install, затем docker-php-ext-enable:

RUN apt-get install -y libmcached-dev zlib1g-dev &&
    pecl install memcached-3.1.5 &&
    docker-php-ext-enable memcached

Советы:

  • Устанавливайте только необходимые расширения, чтобы не увеличивать размер образа.
  • Очистку кешей apt и временных файлов выполняйте в одном RUN, чтобы уменьшить количество слоёв.

Конфигурация PHP

Образы загружают конфигурационные файлы PHP из /usr/local/etc/php/conf.d. Рекомендуемый способ изменить значения — добавить собственный .ini файл в этот каталог; PHP применит его при старте, переопределив параметры по умолчанию.

Текущую директорию конфигурации можно получить через переменную окружения $PHP_INI_DIR (в настоящее время /usr/local/etc/php/conf.d). Используйте переменную, если хотите сделать Dockerfile более устойчивым к изменениям в будущих образах.

Пример добавления ini:

COPY my-php.ini /usr/local/etc/php/conf.d/my-php.ini

Использование Composer

Composer не включён по умолчанию в официальные PHP‑образы. Лучший практический способ — использовать multi‑stage build: взять официальный образ composer как источник бинарника и скопировать его в финальный образ.

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install --no-dev

Преимущества:

  • Не нужно загружать установщик composer в сборочном процессе.
  • Конкретная версия composer задаётся через образ composer:2.

Альтернатива: запуск composer в отдельном контейнере composer:2 для установки зависимостей в volume или на этапе CI.

Пользовательские скрипты запуска

Иногда нужно выполнить миграции или подготовку окружения до старта Apache. Для этого можно переопределить ENTRYPOINT контейнера и запустить собственный bash‑скрипт.

ENTRYPOINT ["bash", "/Docker.sh"]

Содержимое Docker.sh (пример):

php app.php my-migration-command    # run migrations
service cron start# start some services
exec apache2-foreground             # main execution

Замечания:

  • exec apache2-foreground запускает Apache в форграундном режиме, чтобы контейнер не завершил работу после выполнения скрипта.
  • Используйте exec для замены процесса оболочки основным процессом контейнера (PID 1).
  • Следите за остановкой фоновых служб и корректным логированием.

Когда это не подходит

  • Лёгкие статические сайты (без PHP): проще использовать nginx:alpine или статический хостинг.
  • Очень специфичные системные зависимости: если образ требует сложной настройки ОС, возможно, выгоднее использовать виртуальные машины.
  • Если вы не контролируете инфраструктуру выполнения (например, платформа как услуга с ограничениями): уточните совместимость.

Альтернативные подходы

  • Nginx + PHP‑FPM: более распространённая конфигурация для высоконагруженных приложений. Отделяет веб‑сервер от PHP‑процесса.
  • Использование готовых образов фреймворков (Laravel Sail, Symfony images) для ускорения старта.
  • CI/CD: сборка образа в CI с последующим пушем в реестр, а не локальная сборка на машине разработчика.

Мини‑методология сборки образа (шаги)

  1. Подготовьте .dockerignore.
  2. Напишите минимальный Dockerfile на базе php:8.0-apache.
  3. Добавьте необходимые расширения и конфиги в один RUN, чтобы уменьшить слои.
  4. Используйте multi‑stage build для Composer и сборки артефактов.
  5. Протестируйте локально: docker build && docker run.
  6. Добавьте проверку в CI и пушьте тегированный образ в реестр.

Чек‑лист по ролям

Разработчик:

  • Dockerfile лежит в корне.
  • .dockerignore исключает ненужные файлы.
  • composer.json и lock актуальны.

Системный администратор / DevOps:

  • Образ проходит скан на уязвимости.
  • Есть политика обновлений базового образа.
  • Секреты вынесены в секрет‑менеджер.

QA инженер:

  • Запущены интеграционные тесты внутри контейнера.
  • Проверено логирование и код возврата после миграций.

Критерии приёмки

  • Образ собирается в CI без ошибок.
  • Контейнер стартует и слушает порт 80.
  • Миграции выполняются успешно при запуске контейнера (при наличии).
  • Приложение работает под тестовой нагрузкой, основные страницы доступны.

Безопасность и конфиденциальность

  • Не храните пароли/ключи в образе. Используйте переменные окружения или секреты Docker/Kubernetes.
  • Обновляйте базовый образ и следите за CVE для PHP и Apache.
  • Отключайте ненужные модули Apache и PHP для уменьшения поверхности атаки.

Краткая галерея крайних случаев

  • Приложение использует специфичный модуль ядра ОС — контейнеры могут не подойти.
  • Нужен доступ к оборудованию (GPU, специализированные устройства) — потребуется дополнительная конфигурация хоста.

Глоссарий

  • Dockerfile — сценарий сборки Docker‑образа.
  • image — запакованное окружение приложения, готовое к запуску.
  • container — запущенный экземпляр image.

Полезные советы и приёмы

  • Объединяйте apt install и очистку кеша apt в одном RUN: это уменьшит итоговый размер образа.
  • Копируйте только необходимые файлы в финальный образ (COPY с указанием списка файлов/директорий).
  • Если используете Composer, кешируйте ~/.composer/cache между сборками в CI для ускорения.

Сниппет: примерного production Dockerfile

FROM php:8.0-apache
WORKDIR /var/www/html

# Установить зависимости для сборки расширений
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libonig-dev \
    libzip-dev \
    zip \
    unzip \
 && docker-php-ext-configure gd --with-jpeg=/usr/include/ \
 && docker-php-ext-install pdo_mysql mbstring gd zip \
 && apt-get clean && rm -rf /var/lib/apt/lists/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
COPY composer.json composer.json
COPY composer.lock composer.lock
RUN composer install --no-dev --prefer-dist --no-progress --no-interaction

COPY . /var/www/html
COPY my-apache-site.conf /etc/apache2/sites-available/my-apache-site.conf
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf \
    && a2enmod rewrite headers \
    && a2dissite 000-default \
    && a2ensite my-apache-site

EXPOSE 80
ENTRYPOINT ["bash", "/Docker.sh"]

Заключение

Контейнеризация PHP‑сервиса на базе официальных образов — прямой и воспроизводимый путь доставки приложения. Правильная структура Dockerfile, разумный набор расширений, перенос Composer через multi‑stage и аккуратная конфигурация Apache позволяют получить компактный и надёжный образ. Пути отказа обычно связаны с третьими сторонами и системными требованиями — в таких случаях рассмотрите альтернативы, такие как Nginx + PHP‑FPM или VM.

Важно: проверяйте образы на уязвимости и держите зависимости обновлёнными.


Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство