Docker and PHP: Advanced Application Containerization
\n\nContainerization with Docker has long become the standard for developing and deploying PHP applications. Basic knowledge — running a container with PHP and Nginx — is just the first step. At an advanced level, you need to configure multi-stage builds, optimize image size, work with multiple services, manage environment variables, integrate with CI/CD, and build a microservice architecture. In this article, we will break down the key techniques that will help you take PHP containerization to the next level.
\n\n1. Multi-stage builds for PHP
\n\nMulti-stage builds allow you to use multiple FROM instructions in a single Dockerfile. This is ideal for PHP applications where Composer, Node.js, and other tools are needed during the build stage, but only the compiled files and a minimal set of dependencies should end up in the final image.
Example Dockerfile for a Laravel application with multi-stage builds:
\n\n# Stage 1: Install dependencies and build\nFROM composer:2.5 AS vendor\nWORKDIR /app\nCOPY composer.json composer.lock ./\nRUN composer install --no-dev --optimize-autoloader --no-interaction\n\nFROM node:18 AS frontend\nWORKDIR /app\nCOPY package.json package-lock.json ./\nRUN npm ci --only=production\nCOPY resources/ ./resources/\nRUN npm run production\n\n# Stage 2: Final image\nFROM php:8.2-fpm-alpine3.18 AS final\nWORKDIR /var/www/html\n\n# Install required PHP extensions\nRUN apk add --no-cache \\\n libpng-dev \\\n libjpeg-turbo-dev \\\n freetype-dev \\\n libzip-dev \\\n oniguruma-dev \\\n && docker-php-ext-configure gd --with-freetype --with-jpeg \\\n && docker-php-ext-install -j$(nproc) \\\n pdo_mysql \\\n mbstring \\\n gd \\\n zip \\\n opcache\n\n# Copy only necessary files from previous stages\nCOPY --from=vendor /app/vendor/ ./vendor/\nCOPY --from=frontend /app/public/build/ ./public/build/\nCOPY . .\n\n# Optimize for production\nRUN php artisan optimize\n\nEXPOSE 9000\nCMD ["php-fpm"]\n\nKey advantages:
\n- \n
- The final image contains only runtime dependencies (PHP-FPM, extensions, code). \n
- Build tools (Composer, Node.js) do not end up in production. \n
- Significant reduction in image size (from 800-900 MB to 150-200 MB). \n
2. Optimizing Docker image size for PHP
\n\nSmaller images load faster, require less disk space, and reduce the attack surface. Key strategies:
\n\n- \n
- Use alpine versions of base images.
php:8.2-fpm-alpineweighs ~50 MB compared to ~400 MB for the standardphp:8.2-fpm. \n - Minimize the number of layers. Combine
RUNcommands using&&. \n - Delete temporary files. After installing extensions, clean the cache:
docker-php-source deleteandapk del .build-deps. \n - Use
.dockerignore. Exclude.git,node_modules,tests,.env, and other unnecessary files. \n
Example advanced .dockerignore:
.git\n.gitignore\n.env\n.env.example\nnode_modules\ntests\nstorage/logs/*\n!storage/logs/.gitkeep\ndocker-compose.yml\nMakefile\nREADME.md\n\n3. Docker Compose for complex PHP projects
\n\nFor PHP applications using databases, queues, cache, and a web server, docker-compose.yml becomes the central configuration file. Advanced settings include:
- \n
- Networks: Isolate services (e.g., the database should not be accessible from outside). \n
- Volumes:<