Ultimate Guide to Deploying WordPress with Docker: From Setup to Optimization
WordPress powers over 40% of websites globally, but traditional setups often suffer from inconsistencies and scalability issues. Docker simplifies this by containerizing WordPress, MySQL, and Nginx, ensuring reproducibility and efficiency. This guide walks you through deploying a secure, high-performance WordPress site using Docker and optimizing it for speed and reliability.

Introduction
WordPress powers over 40% of websites globally, but traditional setups often suffer from inconsistencies and scalability issues. Docker simplifies this by containerizing WordPress, MySQL, and Nginx, ensuring reproducibility and efficiency. This guide walks you through deploying a secure, high-performance WordPress site using Docker and optimizing it for speed and reliability.
Why Use Docker for WordPress?
- Consistency: Eliminate "it works on my machine" issues with isolated environments.
- Scalability: Easily scale services like Nginx or MySQL independently.
- Security: Isolate vulnerabilities within containers.
- Portability: Deploy the same setup across development, staging, and production.
Prerequisites
- Docker and Docker Compose installed (installation guide).
- A domain name (for SSL).
- Basic terminal/command-line knowledge.
Step 1: Docker Compose Setup
Create a docker-compose.yml
file to define WordPress, MySQL, and Nginx services.
version: '3.8'
services:
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: wp_password
networks:
- wordpress_net
wordpress:
depends_on:
- db
image: wordpress:php8.1-fpm-alpine
volumes:
- wordpress_data:/var/www/html
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: wp_password
WORDPRESS_DB_NAME: wordpress
networks:
- wordpress_net
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- wordpress_data:/var/www/html
- ./certbot/etc/letsencrypt:/etc/letsencrypt
depends_on:
- wordpress
networks:
- wordpress_net
volumes:
db_data:
wordpress_data:
networks:
wordpress_net:
Key Components:
- MySQL: Persistent volume for database storage.
- WordPress: PHP-FPM image for better performance.
- Nginx: Reverse proxy with SSL support.
Step 2: Configure Nginx and SSL
1. Create Nginx Configuration:
In nginx/conf.d/wordpress.conf
, add:
server {
listen 80;
server_name yourdomain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
root /var/www/html;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass wordpress:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Explanation: Redirects HTTP to HTTPS and proxies PHP requests to WordPress.
2. Generate SSL Certificates with Certbot:
docker run -it --rm --name certbot \
-v "./certbot/etc/letsencrypt:/etc/letsencrypt" \
-v "./certbot/var/lib/letsencrypt:/var/lib/letsencrypt" \
-v "./nginx/html:/var/www/html" \
certbot/certbot certonly --webroot -w /var/www/html -d yourdomain.com
Tip: Use --force-renewal to update certificates.
Step 3: Launch the Stack
docker-compose up -d
Verify containers with docker-compose ps. Access your site at https://yourdomain.com.
Optimization Tips
1. Caching with Redis:
Add Redis to docker-compose.yml
:
redis:
image: redis:alpine
networks:
- wordpress_net
Configure WordPress plugins (e.g., Redis Object Cache) for improved performance.
2. Image Optimization:
Use plugins like Smush or ShortPixel to compress images. Adjust PHP limits in uploads.ini
:
upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 512M
Mount this file to WordPress’s PHP config directory.
3. Security Hardening:
- Limit login attempts with Fail2Ban
- Use Cloudflare’s firewall rules for DDoS protection.
4. Backup Strategy:
Schedule daily backups with cron
and docker exec
:
# Backup MySQL
docker exec db sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > backup.sql
# Backup WordPress files
docker cp wordpress:/var/www/html ./wordpress_backup
5. Monitoring:
Use Prometheus + Grafana to track container metrics like CPU/RAM usage.
Troubleshooting Common Issues
- Database Connection Failures: Ensure
WORDPRESS_DB_HOST
matches the MySQL service name - File Permission Errors: Run
chown -R www-data:www-data /var/www/html
in the WordPress container 210. - SSL Errors: Verify Certbot volume mounts and Nginx config paths
Conclusion
By containerizing WordPress with Docker, you gain a portable, scalable, and secure setup. Integrate tools like Redis, Certbot, and Nginx to optimize performance and reliability. For advanced use cases, explore Kubernetes or Traefik for auto-scaling
Next Steps:
- Explore Bitnami’s WordPress image for pre-optimized configurations.
- Implement a CDN for global content delivery.