Docker and PHP: Application Containerization from A to Z
Containerization of PHP applications using Docker has become the standard of modern web development. Whether you are creating a simple landing page or a complex enterprise application, Docker ensures environment consistency at all stages: from local development to production. In this article, we will break down all the stages of creating a Docker infrastructure for a PHP application — from a basic Dockerfile to a full stack with Nginx and MySQL.
Why Docker is Important for a PHP Developer
Traditional PHP development often faces the "it works on my machine" problem. Different PHP versions, extensions, server settings — all of this leads to conflicts. Docker solves this problem once and for all:
- Environment Isolation — each application has its own set of dependencies
- Reproducibility — the same environment on all machines
- Scalability — easily add new services (Redis, Elasticsearch)
- CI/CD Integration — containers are ideal for pipelines
Let's move from theory to practice and create a full Docker environment for a PHP application.
Creating a Basic Dockerfile for PHP
Let's start with the most important thing — the Dockerfile. This is the instruction for building the image of your PHP application. Here is the optimal configuration for a production-ready application:
# Use the official PHP image with FPMFROM php:8.2-fpm-alpine
# Install system dependenciesRUN apk add --no-cache \ git \ unzip \ libpq-dev \ libzip-dev \ && docker-php-ext-install \ pdo_mysql \ zip \ opcache
# Install ComposerCOPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Configure OPcache for productionRUN { \ echo 'opcache.memory_consumption=128'; \ echo 'opcache.interned_strings_buffer=8'; \ echo 'opcache.max_accelerated_files=4000'; \ echo 'opcache.revalidate_freq=2'; \ echo 'opcache.fast_shutdown=1'; \ echo 'opcache.enable_cli=1'; \} > /usr/local/etc/php/conf.d/opcache.ini
# Copy application filesWORKDIR /var/www/htmlCOPY . .
# Set permissionsRUN chown -R www-data:www-data /var/www/html \ && chmod -R 755 storage bootstrap/cache
# Run PHP-FPMCMD ["php-fpm"]
EXPOSE 9000This Dockerfile uses Alpine Linux — a minimal image that significantly reduces the size of the final container. We install only the necessary extensions: pdo_mysql for working with the database and zip for Composer.
Building and Running the Container
# Build the imagedocker build -t my-php-app .
# Run the containerdocker run -d -p 9000:9000 --name php-app my-php-appFull Stack with Nginx and MySQL via docker-compose
A real application rarely consists of a single PHP container. We need a web server and a database. This is where docker-compose comes to the rescue — a tool for orchestrating multiple containers.
Let's create a docker-compose.yml file:
version: '3.8'
services: # PHP-FPM service app: build: context: . dockerfile: Dockerfile container_name: php-app volumes: - ./:/var/www/html networks: - app-network
# Nginx web server nginx: image: nginx:alpine container_name: php-nginx ports: - "8080:80" volumes: - ./:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app networks: - app-network
# MySQL database db: image: mysql:8.0 container_name: php-mysql ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root_password MYSQL_DATABASE: app_database MYSQL_USER: app_user MYSQL_