Монолитные PHP‑приложения часто развиваются в средах, где конфигурация сервера, версии зависимостей и системные утилиты меняются от проекта к проекту. Контейнеризация позволяет зафиксировать весь стек в едином образе, упростить деплой и обеспечить предсказуемость работы в любой инфраструктуре.
Почему контейнеризация?
- Изоляция окружения – каждый сервис получает собственный набор библиотек и настроек.
- Повторяемость – образ, собранный один раз, одинаково работает на локальном ПК, тестовой и прод‑среде.
- Упрощённый масштабируемый деплой – Docker‑Compose, Kubernetes, Swarm.
- Поддержка CI/CD – автоматическое построение и тестирование образов.
Подготовка проекта
Перед тем как упаковать приложение в контейнер, необходимо убедиться, что проект:
- Хранит все зависимости в
composer.jsonиcomposer.lock. - Не полагается на глобальные системные расширения, которые отсутствуют в официальных PHP‑образах.
- Имеет отдельные файлы конфигурации (например,
.env) и умеет работать в режимеproduction.
Шаг 1. Создание Dockerfile
Самый простой Dockerfile для монолита на PHP 8.2 выглядит так:
FROM php:8.2-fpm-alpine
# Устанавливаем системные зависимости
RUN apk add --no-cache \
git \
unzip \
libzip-dev \
&& docker-php-ext-install zip pdo_mysql
# Копируем composer и устанавливаем зависимости
COPY --from=composer:2.6 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
# Копируем исходный код проекта
COPY . .
# Права доступа для www-data
RUN chown -R www-data:www-data /var/www/html
EXPOSE 9000
CMD ["php-fpm"]
Не забудьте добавить .dockerignore, чтобы исключить лишние файлы из контекста сборки:
.git
vendor
node_modules
.env.local
Dockerfile
docker-compose.yml
Шаг 2. Docker‑Compose для сервисов
Большинство монолитов используют базу данных и очередь. Описание в docker-compose.yml позволяет запустить всё локально одной командой:
version: "3.9"
services:
app:
build: .
container_name: php_monolith_app
volumes:
- ./:/var/www/html
environment:
- APP_ENV=prod
- DATABASE_URL=mysql://user:password@db:3306/app_db
depends_on:
- db
ports:
- "9000:9000"
db:
image: mysql:8.0
container_name: php_monolith_db
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: app_db
MYSQL_USER: user
MYSQL_PASSWORD: password
volumes:
- db_data:/var/lib/mysql
ports:
- "3306:3306"
volumes:
db_data:
Запуск: docker-compose up -d --build.
Шаг 3. Перенос конфигураций
Для гибкой работы в разных окружениях вынесите параметры в переменные окружения. В PHP‑приложениях это обычно реализуется через vlucas/phpdotenv:
# .env.example
APP_ENV=dev
APP_DEBUG=1
DATABASE_URL=mysql://user:password@localhost:3306/app_db
В Docker‑Compose уже задали APP_ENV=prod. При сборке образа можно задать ARG APP_ENV и использовать в php.ini.
Шаг 4. Тестирование и CI/CD
Для автоматической проверки образов рекомендуется добавить шаги в CI‑pipeline (GitHub Actions, GitLab CI, Bitbucket Pipelines):
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: myrepo/php-monolith:${{ github.sha }}
- name: Run tests in container
run: |
docker run --rm myrepo/php-monolith:${{ github.sha }} php vendor/bin/phpunit
Таким образом, каждый коммит приводит к построению нового образа, проверке тестов и публикации в реестр.
Заключение
Контейнеризация монолитного PHP‑приложения – процесс, который начинается с анализа зависимостей и заканчивается полной автоматизацией деплоя. Следуя пошаговому плану, вы получаете предсказуемую, масштабируемую и безопасную инфраструктуру, готовую к работе в любой облачной или on‑premise среде.
RybinskLab предоставляет комплексные услуги по разработке, контейнеризации и настройке CI/CD для PHP‑проектов любой сложности. Мы поможем мигрировать ваш монолит в Docker, оптимизировать архитектуру и обеспечить стабильный процесс доставки кода.