Docs / Programming & Development / Writing Effective Dockerfiles for PHP Applications

Writing Effective Dockerfiles for PHP Applications

By Admin · Mar 27, 2026 · Updated Apr 23, 2026 · 323 views · 2 min read

Base Image

FROM php:8.3-fpm-alpine

Alpine Linux keeps the image small. Use -fpm for web applications behind Nginx.

Installing Extensions

# System dependencies for common PHP extensions
RUN apk add --no-cache \
    libpng-dev \
    libzip-dev \
    icu-dev \
    postgresql-dev \
    oniguruma-dev

# Install PHP extensions
RUN docker-php-ext-install \
    pdo_mysql \
    pdo_pgsql \
    mbstring \
    zip \
    gd \
    intl \
    opcache \
    bcmath

Composer Dependencies

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Install dependencies (cache-friendly layer ordering)
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts

# Then copy application code
COPY . .
RUN composer dump-autoload --optimize

OPcache Configuration

# /usr/local/etc/php/conf.d/opcache.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.interned_strings_buffer=16
opcache.jit=tracing
opcache.jit_buffer_size=64M

Tip Set validate_timestamps=0 in production — it tells OPcache to never check if files changed, which is safe in containers where code is immutable.

Complete Production Dockerfile

FROM php:8.3-fpm-alpine AS base

# System deps
RUN apk add --no-cache libpng libzip icu postgresql-libs oniguruma

FROM base AS build
RUN apk add --no-cache libpng-dev libzip-dev icu-dev postgresql-dev oniguruma-dev
RUN docker-php-ext-install pdo_mysql pdo_pgsql mbstring zip gd intl opcache bcmath

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
WORKDIR /var/www
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts
COPY . .
RUN composer dump-autoload --optimize

FROM base
COPY --from=build /usr/local/lib/php/extensions/ /usr/local/lib/php/extensions/
COPY --from=build /usr/local/etc/php/conf.d/ /usr/local/etc/php/conf.d/
COPY --from=build /var/www /var/www

COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/
COPY docker/php/php.ini /usr/local/etc/php/conf.d/

RUN adduser -D -u 1000 app
USER app
WORKDIR /var/www

EXPOSE 9000
CMD ["php-fpm"]

Nginx Companion

server {
    listen 80;
    root /var/www/public;
    index index.php;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
Image Size Configuration
~450 MB php:8.3-fpm (Debian)
~120 MB php:8.3-fpm-alpine
~80 MB Multi-stage with alpine

Was this article helpful?