Deploying Docker for Symfony Development in 6 Steps
I’ll walk you through six steps to set up Docker with Symfony. This detailed guide covers everything you need to configure a complete Symfony development environment using Docker.
Benefits of this setup
- Isolated and reproducible environment
- Optimized PHP configuration for Symfony
- MySQL database with phpMyAdmin
- Nginx configured for Symfony
- Automation scripts with Makefile
- Proper user permission management
Services included
- PHP 8.2-FPM with all required extensions
- Nginx as the web server
- MySQL 8.0 as the database
- phpMyAdmin for database management
Step 1: Install Docker
Windows:
- Download Docker Desktop from docker.com.
- Run the installer and follow the instructions.
- Restart your computer if necessary.
macOS:
- Download Docker Desktop for Mac.
- Drag Docker into the Applications folder.
- Launch Docker from the Launchpad.
Ubuntu/Debian:
# Update packages
sudo apt update# Install dependencies
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release# Add Docker’s official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg — dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg# Add Docker repository
echo “deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable” \
| sudo tee /etc/apt/sources.list.d/docker.list > /dev/null# Install Docker
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
Verify installation:
docker — version
docker-compose — version
Step 2: Create a docker-compose.yml file
At the root of your project, create a docker-compose.yml file:
version: ‘3.8’
services:
# PHP-FPM Service
php:
build:
context: .
dockerfile: Dockerfile
container_name: symfony_php
volumes:
— .:/var/www/html
networks:
— symfony_network
depends_on:
— database# Nginx Service
nginx:
image: nginx:alpine
container_name: symfony_nginx
ports:
— “8080:80”
volumes:
— .:/var/www/html
— ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
— symfony_network
depends_on:
— php# MySQL Database Service
database:
image: mysql:8.0
container_name: symfony_mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: symfony_db
MYSQL_USER: symfony
MYSQL_PASSWORD: symfony
ports:
— “3306:3306”
volumes:
— mysql_data:/var/lib/mysql
networks:
— symfony_network# phpMyAdmin Service (optional)
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: symfony_phpmyadmin
environment:
PMA_HOST: database
PMA_PORT: 3306
PMA_USER: root
PMA_PASSWORD: root
ports:
— “8081:80”
networks:
— symfony_network
depends_on:
— databasenetworks:
symfony_network:
driver: bridgevolumes:
mysql_data:
Step 3: Create a Dockerfile
At the root of your project, add a Dockerfile:
FROM php:8.2-fpm
# Build arguments
ARG USER_ID=1000
ARG GROUP_ID=1000# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
libzip-dev \
libicu-dev \
&& rm -rf /var/lib/apt/lists/*# Install PHP extensions
RUN docker-php-ext-install \
pdo_mysql \
mbstring \
exif \
pcntl \
bcmath \
gd \
zip \
intl# Install Composer
COPY — from=composer:latest /usr/bin/composer /usr/bin/composer# Create user with same UID/GID as host
RUN groupadd -g ${GROUP_ID} appgroup && \
useradd -u ${USER_ID} -g appgroup -m appuser# Set working directory
WORKDIR /var/www/html# Copy PHP config
COPY docker/php/php.ini /usr/local/etc/php/php.ini# Set permissions
RUN chown -R appuser:appgroup /var/www/html# Use non-root user
USER appuser# Expose port
EXPOSE 9000# Default command
CMD [“php-fpm”]
Step 4: Configure PHP and Nginx
PHP configuration
Create docker/php/php.ini:
[PHP]
memory_limit = 512M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_vars = 3000display_errors = On
display_startup_errors = On
log_errors = On
error_log = /var/log/php_errors.logsession.save_handler = files
session.save_path = /tmpopcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.revalidate_freq = 2
opcache.fast_shutdown = 1date.timezone = Europe/Paris
Nginx configuration
Create docker/nginx/default.conf:
server {
listen 80;
server_name localhost;
root /var/www/html/public;
index index.php index.html;location / {
try_files $uri $uri/ /index.php$is_args$args;
}location ~ ^/index\.php(/|$) {
fastcgi_pass php:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
internal;
}location ~ \.php$ {
return 404;
}error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control “public, immutable”;
}
}
Step 5: Automate with Composer, Init Script & Makefile
Init script
Create init-project.sh:
#!/bin/bash
echo “🚀 Initializing Symfony project with Docker…”
echo “📦 Building Docker images…”
docker-compose buildecho “🔄 Starting containers…”
docker-compose up -decho “⏳ Waiting for services…”
sleep 10if [ ! -f “composer.json” ]; then
echo “🎵 Installing Symfony…”
docker-compose exec php composer create-project symfony/skeleton . — no-interaction
docker-compose exec php composer require webapp — no-interaction
fiecho “📚 Installing dependencies…”
docker-compose exec php composer installecho “🗄️ Setting up database…”
docker-compose exec php php bin/console doctrine:database:create — if-not-exists
docker-compose exec php php bin/console doctrine:migrations:migrate — no-interactionecho “✅ Project initialized successfully!”
echo “🌐 App available at: http://localhost:8080"
echo “🗄️ phpMyAdmin available at: http://localhost:8081"
Make it executable:
chmod +x init-project.sh
Makefile
.PHONY: help build up down restart logs shell composer sf install
help: ## Show available commands
@grep -E ‘^[a-zA-Z_-]+:.*?## .*$$’ $(MAKEFILE_LIST) | sort | awk ‘BEGIN {FS = “:.*?## “}; {printf “\033[36m%-20s\033[0m %s\n”, $$1, $$2}’build: ## Build Docker images
docker-compose buildup: ## Start containers
docker-compose up -ddown: ## Stop containers
docker-compose downrestart: ## Restart containers
docker-compose restartlogs: ## View container logs
docker-compose logs -fshell: ## Open a shell in the PHP container
docker-compose exec php bashcomposer: ## Run Composer commands
docker-compose exec php composer $(filter-out $@,$(MAKECMDGOALS))sf: ## Run Symfony console commands
docker-compose exec php php bin/console $(filter-out $@,$(MAKECMDGOALS))install: ## Full project installation
chmod +x init-project.sh && ./init-project.sh%:
@:
Step 6: Run Docker Containers
Basic commands
# 1. Build images
docker-compose build# 2. Start containers in the background
docker-compose up -d# 3. Check running containers
docker-compose ps# 4. View logs
docker-compose logs -f# 5. Stop containers
docker-compose down
With Makefile
# Full installation
make install# Start project
make up# View logs
make logs# Run Symfony commands
make sf cache:clear
make sf make:controller HomeController# Run Composer commands
make composer require symfony/orm-pack
make composer install# Access PHP container shell
make shell
Symfony Environment Configuration
Edit or create .env.local:
DATABASE_URL=”mysql://symfony:symfony@database:3306/symfony_db?serverVersion=8.0"
APP_ENV=dev
APP_DEBUG=true
APP_SECRET=your_secret_key_here# Optional mailer config
MAILER_DSN=smtp://localhost:1025
Final Verification
Once the containers are running, verify:
- Symfony app → http://localhost:8080
- phpMyAdmin → http://localhost:8081
- MySQL database → available on port 3306
✅ Your Symfony development environment with Docker is now ready! 🎉
