A clean Docker setup for a Symfony project
PHP-FPM, Nginx and MySQL with Docker Compose — a simple, reproducible foundation for building a Symfony application as a team.
"It works on my machine": with Docker, that sentence has no reason to exist. The whole team shares the same environment, from the PHP version to the installed extensions. Here is the foundation I use to start a Symfony project: three services, a short Dockerfile and a few commands.
The architecture
- php: PHP-FPM with the extensions Symfony needs;
- nginx: the web server, forwarding PHP requests to FPM;
- database: MySQL 8.
The PHP Dockerfile
FROM php:8.3-fpm
RUN apt-get update && apt-get install -y git unzip libicu-dev libzip-dev \
&& docker-php-ext-install intl pdo_mysql opcache zip \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/app
Copying Composer from its official image avoids a manual install and guarantees a recent version.
The compose.yaml file
services:
php:
build: .
volumes:
- ./:/var/www/app
depends_on: [database]
nginx:
image: nginx:1.27-alpine
ports: ["8080:80"]
volumes:
- ./:/var/www/app
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on: [php]
database:
image: mysql:8.0
environment:
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: app
MYSQL_ROOT_PASSWORD: root
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
The named volume db-data keeps the database between restarts.
The Nginx configuration
server {
listen 80;
root /var/www/app/public;
location / {
try_files $uri /index.php$is_args$args;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass php:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
internal;
}
}
fastcgi_pass php:9000 works because Docker Compose creates a network where every service is reachable by its name.
Wiring Symfony
In .env.local, the database host is simply the service name:
DATABASE_URL="mysql://app:app@database:3306/app?serverVersion=8.0"
Then start everything:
docker compose up -d --build
docker compose exec php composer install
docker compose exec php bin/console doctrine:migrations:migrate
The application answers on http://localhost:8080.
My tips
- A Makefile with shortcuts (
make up,make sh,make migrate) saves the whole team time. - Xdebug on demand: install it in a separate Dockerfile stage or enable it through an environment variable, so it doesn't slow down everyday work.
- Never commit secrets: keep credentials in
.env.localor in Symfony's secrets vault. - To go further, Kévin Dunglas's open-source symfony-docker project offers a very complete base with FrankenPHP and local HTTPS.
This setup is deliberately minimal: it reads in two minutes, and anyone can extend it to fit the project.