Контейнеризация PHP 8.4 при помощи Docker. Подробное руководство
Основные подходы к созданию Docker образа с PHP 8.4
Как получить минимальный и эффективный образ для PHP 8.4?
Оптимальным решением является использование официального образа php:8.4-fpm-alpine. Этот образ базируется на Alpine Linux, что даёт малый размер (около 50 МБ) и высокую безопасность. Ниже приведён Dockerfile с установкой нескольких популярных расширений.
FROM php:8.4-fpm-alpine
RUN apk add --no-cache \
libzip-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
oniguruma-dev \
libxml2-dev \
postgresql-dev \
&& docker-php-ext-install \
pdo_mysql \
pdo_pgsql \
mbstring \
exif \
pcntl \
bcmath \
gd \
zip \
intl \
opcache \
&& pecl install redis \
&& docker-php-ext-enable redis \
&& apk del --purge \
libzip-dev \
libpng-dev \
libjpeg-turbo-dev \
freetype-dev \
oniguruma-dev \
libxml2-dev \
postgresql-dev \
&& rm -rf /var/cache/apk/*
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
USER www-data
EXPOSE 9000
CMD ["php-fpm"]Docker php 8.4 (образ docker с php 8.4)
Пояснение: apk add --no-cache устанавливает зависимости для сборки расширений, docker-php-ext-install компилирует и включает расширения, pecl install redis добавляет Redis, а COPY --from=composer копирует Composer из отдельного образа. Финальная очистка удаляет лишние пакеты.
Типичные проблемы и их решения:
- Ошибка
configure: error: Package requirements (libcurl >= 7.29.0) were not met- не хватаетcurl-dev. Добавьте вapk add curl-dev. - Проблема с правами доступа при записи в volume - в образе используется пользователь
www-data. Убедитесь, что хостовые папки имеют соответствующие права (например,chown -R 82:82 .). - Ошибка
Fatal error: Uncaught Error: Call to undefined function bcdiv()- расширение bcmath не включено. Добавьте его в списокdocker-php-ext-install.
Вариант 1. Как построить образ на основе Debian (php:8.4-fpm) для совместимости с устаревшими расширениями?
В случаях, когда Alpine не поддерживает некоторые библиотеки (например, imap или mssql), лучше взять Debian-версию образа. Размер будет больше (~200 MB), но совместимость выше.
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y \
libzip-dev \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libonig-dev \
libxml2-dev \
libpq-dev \
libcurl4-openssl-dev \
libssl-dev \
unzip \
&& docker-php-ext-install \
pdo_mysql \
pdo_pgsql \
mbstring \
exif \
pcntl \
bcmath \
gd \
zip \
intl \
opcache \
&& pecl install xdebug \
&& docker-php-ext-enable xdebug \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*Проблема:
При установке расширения gd часто возникает конфликт версий libpng. Решение - явно указать флаги конфигурации: --with-freetype --with-jpeg. Добавьте перед docker-php-ext-configure gd --with-freetype --with-jpeg.
Вариант 2. Как совместить PHP-FPM и Nginx в одном контейнере?
Для разработки удобно иметь единый контейнер с двумя процессами. Используется супервизор (supervisor) для запуска обоих сервисов.
FROM php:8.4-fpm-alpine
RUN apk add --no-cache nginx supervisor \
&& docker-php-ext-install opcache \
&& mkdir -p /run/nginx
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/php.ini /usr/local/etc/php/conf.d/custom.ini
WORKDIR /var/www/html
EXPOSE 80 9000
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]Проблема:
Nginx может не дождаться запуска PHP-FPM, что вызовет ошибку 502. В конфигурации супервизора нужно использовать autorestart=true и задать startsecs=0 для fpm.
Вариант 3. Как использовать многостадийную сборку для уменьшения финального образа?
Сборка расширений в первом образе с dev-зависимостями, затем копирование артефактов в чистый минимальный образ.
FROM php:8.4-fpm-alpine AS builder
RUN apk add --no-cache autoconf build-base linux-headers libzip-dev \
&& docker-php-ext-install zip
FROM php:8.4-fpm-alpine
COPY --from=builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions
RUN docker-php-ext-enable zip
# далее установка приложения...Проблема:
Зависимости расширений (.so файлы) могут требовать дополнительные библиотеки (например, libzip.so). Финальный образ также должен содержать runtime-зависимости. Добавьте apk add --no-cache libzip во второй образ.
Расширенные примеры использования Docker с PHP 8.4
Пример 1. Полный Dockerfile с предустановленным Xdebug и настройкой окружения
FROM php:8.4-fpm-alpine
RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug-3.4.0 \
&& docker-php-ext-enable xdebug \
&& apk del $PHPIZE_DEPS
COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
ENV XDEBUG_MODE=debug
ENV XDEBUG_CLIENT_HOST=host.docker.internal
CMD ["php-fpm"]После сборки (docker build -t php84-xdebug .) и запуска контейнера, Xdebug будет активен. Проверка: php -v должен показать версию с Xdebug.
Пример 2. Docker Compose с PHP 8.4, Nginx, PostgreSQL и Redis
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./src:/var/www/html
expose:
- 9000
networks:
- app-net
nginx:
image: nginx:alpine
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
ports:
- "8080:80"
networks:
- app-net
depends_on:
- app
db:
image: postgres:17-alpine
environment:
POSTGRES_DB: testdb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
networks:
- app-net
redis:
image: redis:7-alpine
networks:
- app-net
networks:
app-net:Запуск: docker compose up -d. Приложение доступно на http://localhost:8080.
Пример 3. Установка дополнительных PHP расширений через PECL в Alpine
FROM php:8.4-fpm-alpine
RUN apk add --no-cache \
$PHPIZE_DEPS \
libzmq zeromq-dev \
librabbitmq-c-dev \
&& pecl install zmq-1.1.3 \
&& pecl install amqp-2.0.0 \
&& docker-php-ext-enable zmq amqp \
&& apk del $PHPIZE_DEPS \
&& rm -rf /tmp/pear/После сборки расширения zmq и amqp будут доступны. Проверка: php -m | grep -E 'zmq|amqp'.
Пример 4. Многостадийная сборка с Composer и оптимизацией автозагрузчика
FROM composer:latest AS composer
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
FROM php:8.4-fpm-alpine
COPY --from=composer /app/vendor /var/www/vendor
COPY src/ /var/www/html
RUN docker-php-ext-install opcache pdo_mysql
USER www-dataСборка: docker build -t php84-app . . Результат - образ без зависимостей для разработки, с оптимизированным автозагрузчиком.
Пример 5. Настройка часового пояса и локали в Debian-образе
FROM php:8.4-fpm
RUN apt-get update && apt-get install -y locales \
&& echo "ru_RU.UTF-8 UTF-8" >> /etc/locale.gen \
&& locale-gen ru_RU.UTF-8 \
&& ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime \
&& dpkg-reconfigure -f noninteractive tzdata \
&& apt-get cleanПосле сборки контейнер будет использовать московское время и русскую локаль. Проверка: date в контейнере покажет правильное время.