Создание изолированной среды разработки на базе Docker с использованием PHP

Не ставьте PHP и расширения напрямую на систему – проще использовать контейнеры. Это избавит от конфликтов версий и сломанных зависимостей. Вместо глобальных установок, настройте всё в отдельном пространстве с нужной версией интерпретатора и нужными модулями.

Используйте образ php:8.2-apache или php:8.2-fpm – зависит от того, нужен ли встроенный веб-сервер или связка с Nginx. Не забудьте сразу подключить volume для исходников и пробросить порты. Так можно редактировать код на хосте и сразу видеть результат в браузере.

Для управления зависимостями нужен composer. Установите его прямо внутри контейнера или через отдельный сервис в docker-compose. Подключите к файлу docker-compose отдельный том с кэшем – ускорит работу и не придётся тянуть одни и те же пакеты заново при каждой сборке.

Не смешивайте сервисы в одном контейнере. Отдельно запустите базу данных, почтовый тестовый сервер, очередь сообщений. Используйте docker-compose с минимальными настройками: несколько строк – и у вас готовый стек. Переменные окружения – через .env, пути к конфигам – через volumes.

Если нужно пошагово контролировать, что происходит, добавьте в конфиг tty: true и stdin_open: true. Это даст возможность подключиться внутрь и тестировать, не перезапуская всё заново. И не забудьте про xdebug, если работаете с отладкой – он настраивается за пару строк в ini-файле.

Настройка Dockerfile и docker-compose для запуска PHP-приложения

Сразу укажи базовый образ с нужной версией языка:

FROM php:8.2-fpm

Добавь установку зависимостей и расширений:

RUN apt-get update && apt-get install -y \
libpq-dev \
libzip-dev \
unzip \
&& docker-php-ext-install pdo pdo_pgsql zip

Чтобы избежать ручного копирования composer, вставь это:

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

Скрипты, исходники и конфиги удобно кидать вот так:

WORKDIR /var/www
COPY . .

Теперь файл конфигурации для orchestration. Назови его docker-compose.yml:

version: "3.9"
services:
app:
build: .
volumes:
- .:/var/www
ports:
- "9000:9000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:

Если нужно веб-прокси (например, nginx), добавь третий сервис с привязкой к app:9000. Проверь, чтобы путь fastcgi_pass совпадал с именем сервиса.

Не забудь .dockerignore, чтобы не тянуть лишние файлы в образ:

vendor
node_modules
.git
.env

После сборки (docker compose up --build) проверь, чтобы контейнер не падал – это обычно либо из-за прав, либо из-за нехватающих расширений. Если используешь Laravel – не забудь php artisan config:clear внутри сервиса.

Организация разработки и отладки PHP-кода внутри контейнера

Настройка Xdebug

В конфигурации расширения xdebug укажи:


xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal

Это позволит подключиться из IDE без танцев с IP. Убедись, что порт (обычно 9003) проброшен наружу. В PhpStorm включи настройку «Can accept external connections».

Работа с live-изменениями

Для автоперезапуска кода без пересборки – поставь inotify-tools и используй его в связке с supervisord или entr. Это особенно удобно при использовании фреймворков с CLI-серверами. Не забывай отключать кеширование опкодов: opcache.enable=0.

Логируй всё в STDOUT – так сообщения сразу попадут в консоль, где запущен контейнер, или в систему логирования, если она настроена. Это проще, чем вылавливать файлы логов в папках, скрытых глубоко внутри контейнера.

Если контейнер не запускается или ведёт себя странно – запусти его с -it --entrypoint /bin/sh, проверь конфиги и установленные расширения прямо изнутри.