Не ставьте 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
, проверь конфиги и установленные расширения прямо изнутри.