Why Your PHP Project Deserves Docker
\n\nHave you ever spent half a day explaining to a new developer how to set up the environment? Or encountered a situation where the code works on your localhost but crashes on the server? Sound familiar? Then this article is for you.
Docker is not just a trendy buzzword. It's a tool that turns the phrase "it works on my machine" into "it works for everyone." For a PHP developer, containerization is a superpower: you package the application, web server, and database into lightweight containers that behave identically on any machine.
\n\nIn this guide, we won't go through boring theory. We'll get straight to business: we'll write a Dockerfile for PHP, set up the Nginx + PHP-FPM + MySQL stack using Docker Compose, and deploy a real application. Poof — your project is ready for deployment!
\n\nWhat is Containerization and Why Does a PHP Developer Need It?
\n\nImagine you're moving to a new apartment. Instead of assembling the furniture from scratch each time (installing PHP, configuring Apache, adding modules), you simply take a ready-made box with your environment. Docker is like those boxes. They are called containers.
\n\nThis is especially relevant for PHP. PHP versions change, different extensions are required (gd, mysqli, redis), and everything needs to be stable in production. Containerization solves three main problems:
\n- \n
- Reproducibility — the environment is the same for everyone: developer, tester, server. \n
- Isolation — projects don't conflict (your old site will never break again due to a PHP update). \n
- Ease of deployment — launch with a single command
docker-compose up. \n
Preparing a Dockerfile for a PHP Application
\n\nLet's start with the main thing — creating an image for our PHP project. Let's say we have a simple application on PHP 8.2 using PDO to work with MySQL. Here's what a minimal Dockerfile looks like:
# Use the official PHP 8.2 image with FPM\nFROM php:8.2-fpm-alpine\n\n# Install necessary system packages\nRUN apk add --no-cache \\\n nginx \\\n supervisor \\\n libpq-dev \\\n && docker-php-ext-install pdo pdo_mysql\n\n# Copy configs (we'll create them later)\nCOPY ./docker/nginx.conf /etc/nginx/nginx.conf\nCOPY ./docker/supervisord.conf /etc/supervisord.conf\n\n# Copy application code\nCOPY . /var/www/html\n\n# Write permissions for logs and cache\nRUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache\n\n# Expose ports\nEXPOSE 80\n\n# Start supervisor (it will manage nginx and php-fpm)\nCMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]\n\nWhat's important here? We use the alpine version — it's significantly smaller. We install only the necessary extensions via docker-php-ext-install. And yes, we use supervisor so that both Nginx and PHP-FPM run inside a single container. This is convenient for small projects.
Creating the Nginx Config
\n\nNow we need to configure the web server. Create the file docker/nginx.conf:
worker_processes auto;\nevents {\n worker_connections 1024;\n}\n\nhttp {\n include /etc/nginx/mime.types;\n default_type application/octet-stream;\n\n server {\n listen 80;\n server_name _;\n root /var/www/html/public;\n index index.php index.html;\n\n location / {\n try_files $uri $uri/ /index.php?$query_string;\n }\n\n location ~ \\.php$ {\n fastcgi_pass 127.0.0.1:9000;\n fastcgi_index index.php;\n fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n include fastcgi_params;\n }\n }\n}\n\nNote: PHP-FPM listens on port 9000 inside the container.