У вас есть PHP-проект, который работает на старом сервере с кучей настроек, и вы хотите упаковать его в Docker? Эта статья поможет пройти путь от «работает только у меня» до «работает везде» без боли и лишних нервов.

Digital-студия WNDER

Что такое Docker и зачем он PHP-разработчику

Docker — это инструмент, который упаковывает ваше приложение и все его зависимости в изолированный контейнер. Представьте, что вы собираете чемодан: вместо того чтобы каждый раз искать нужные вещи по всей квартире, вы кладёте всё необходимое в один ящик и берёте его с собой куда угодно. Контейнер — это тот самый ящик.

Для PHP-разработчика это означает, что вам больше не нужно переживать о версиях PHP, расширениях, настройках веб-сервера и базах данных на разных машинах. Всё, что нужно, уже внутри контейнера.

Правило: Никогда не запускайте Docker от имени root без необходимости. Используйте непривилегированного пользователя внутри контейнера — это снижает риски безопасности.

С чего начать миграцию: анализ проекта

Прежде чем писать Dockerfile, разберитесь, что у вас есть. Составьте список зависимостей: версия PHP, расширения (например, pdo_mysql, gd, mbstring), веб-сервер (Apache или Nginx), база данных (MySQL, PostgreSQL), а также дополнительные сервисы (Redis, Memcached).

Проверьте, как проект конфигурируется: через переменные окружения, файлы .env или прямо в коде. В Docker лучше всего использовать переменные окружения — их легко передавать в контейнер.

Если у вас есть composer.json и composer.lock, зафиксируйте версии зависимостей. Это избавит от сюрпризов при сборке.

Пишем Dockerfile для PHP-приложения

Dockerfile — это инструкция по сборке образа. Начнём с простого примера для PHP 8.1 с Apache.

А вот и сам Dockerfile:

FROM php:8.1-apache

# Устанавливаем расширения
RUN docker-php-ext-install pdo_mysql mbstring gd

# Копируем код
COPY . /var/www/html/

# Настраиваем права
RUN chown -R www-data:www-data /var/www/html

# Включаем mod_rewrite
RUN a2enmod rewrite

EXPOSE 80

Это минимальный набор. Если проект использует Composer, добавьте установку зависимостей:

FROM composer:2 AS composer

FROM php:8.1-apache

RUN docker-php-ext-install pdo_mysql mbstring gd

COPY --from=composer /usr/bin/composer /usr/bin/composer

COPY . /var/www/html/

WORKDIR /var/www/html

RUN composer install --no-dev --optimize-autoloader

RUN chown -R www-data:www-data /var/www/html

EXPOSE 80

Обратите внимание на многоступенчатую сборку: мы используем отдельный образ для Composer, чтобы не тащить его в финальный образ.

Лайфхак: Добавьте в .dockerignore файлы, которые не нужны в контейнере: .git, node_modules, tests, .env. Это ускорит сборку и уменьшит размер образа.

Настройка docker-compose для локальной разработки

Для удобства используйте docker-compose. Он позволяет описать все сервисы (PHP, MySQL, Redis) в одном файле.

version: '3.8'

services:
  app:
    build: .
    ports:
      - "8080:80"
    volumes:
      - .:/var/www/html
    depends_on:
      - db
    environment:
      - DB_HOST=db
      - DB_USER=root
      - DB_PASSWORD=secret

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Теперь достаточно выполнить docker-compose up -d, и у вас поднимется всё окружение. Код монтируется внутрь контейнера через volume, так что изменения видны сразу.

Типичные ошибки и как их избежать

Миграция редко проходит гладко. Вот несколько граблей, на которые наступают почти все.

Ошибка Причина Решение
Права на файлы Контейнер работает от www-data, а файлы принадлежат root Выполнить chown в Dockerfile или монтировать с правильными правами
Отсутствие расширений Забыли установить нужное расширение PHP Добавить docker-php-ext-install в Dockerfile
Медленная сборка Копирование всего проекта до установки зависимостей Сначала COPY composer.json и composer.lock, потом composer install, затем COPY остального

Ещё одна частая проблема — сессии и кеш. Если вы используете файловые сессии, при перезапуске контейнера они теряются. Решение: хранить сессии в Redis или в базе данных.

Деплой в продакшен

Когда локально всё работает, пора выкатывать на сервер. В продакшене не монтируйте код через volume — лучше собрать образ и запустить его. Используйте переменные окружения для конфиденциальных данных.

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

docker build -t my-php-app .
docker run -d -p 80:80 --name my-app --env-file .env my-php-app

Для управления контейнерами в продакшене часто используют Docker Swarm или Kubernetes. Но для небольших проектов достаточно docker-compose.

Совет: Настройте healthcheck в Dockerfile, чтобы Docker мог проверять, что приложение живо. Например: HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1

Что в итоге

Миграция PHP-проекта в Docker — это не страшно, если действовать последовательно. Сначала проанализируйте зависимости, затем напишите Dockerfile, настройте docker-compose для локальной разработки, протестируйте и только потом деплойте в продакшен.

Главные плюсы: единое окружение для всех разработчиков, лёгкое масштабирование и изоляция сервисов. Главное — не забывайте про безопасность и оптимизацию образов.

Начните с малого: упакуйте один сервис, например, только PHP. Убедитесь, что он работает, и постепенно добавляйте остальные. Удачи!

Студия WNDER