Production-ready WordPress with automatic HTTPS using Docker and Caddy. Includes separate configurations for local development and production deployment.
- π One-command deployment
- π Automatic HTTPS with Let's Encrypt (production)
- π³ Fully containerized
- π§ Separate local and production configs
- π¦ Persistent data storage
- Docker (20.10.0+)
- Docker Compose (2.0.0+)
- A domain pointing to your server (production only)
# 1. Clone and setup
git clone https://github.com/Sagar-Kap/dockerised-wordpress.git
cd dockerised-wordpress
# 2. Configure environment
cp .env.example .env
nano .env # Use simple passwords for local
# 3. Start
docker compose -f docker-compose.local.yml up -d
# 4. Access at http://localhost:8080# 1. Clone and setup
git clone https://github.com/Sagar-Kap/dockerised-wordpress.git
cd dockerised-wordpress
# 2. Configure environment
cp .env.example .env
nano .env # Set DOMAIN, CADDY_EMAIL, and strong passwords
# 3. Verify DNS points to your server
nslookup yourdomain.com
# 4. Start
docker compose -f docker-compose.production.yml up -d
# 5. Access at https://yourdomain.comwordpress-docker-caddy/
βββ docker-compose.local.yml # Local development
βββ docker-compose.production.yml # Production
βββ Caddyfile.local # HTTP on port 8080
βββ Caddyfile.production # HTTPS with auto SSL
βββ .env.example # Environment template
| Feature | Local | Production |
|---|---|---|
| Compose File | docker-compose.local.yml |
docker-compose.production.yml |
| URL | http://localhost:8080 | https://yourdomain.com |
| SSL | β No | β Automatic |
| Ports | 8080 | 80, 443 |
# Start
docker compose -f docker-compose.local.yml up -d
# Stop
docker compose -f docker-compose.local.yml down
# View logs
docker compose -f docker-compose.local.yml logs -f
# Restart
docker compose -f docker-compose.local.yml restart# Start
docker compose -f docker-compose.production.yml up -d
# Stop
docker compose -f docker-compose.production.yml down
# View logs
docker compose -f docker-compose.production.yml logs -f
# Update WordPress
docker compose -f docker-compose.production.yml pull
docker compose -f docker-compose.production.yml up -dLocal:
docker exec wordpress-mysql-local mysqldump -u root -p${MYSQL_ROOT_PASSWORD} \
${MYSQL_DATABASE} > backup-$(date +%Y%m%d).sqlProduction:
docker exec wordpress-mysql mysqldump -u root -p${MYSQL_ROOT_PASSWORD} \
${MYSQL_DATABASE} > backup-$(date +%Y%m%d).sqlLocal:
docker cp wordpress-app-local:/var/www/html/wp-content ./wp-content-backupProduction:
docker cp wordpress-app:/var/www/html/wp-content ./wp-content-backup# Check Caddy logs
docker compose -f docker-compose.production.yml logs caddy
# Verify DNS
nslookup yourdomain.com
# Check ports are open
sudo netstat -tlnp | grep -E ':(80|443)'# Check services are running
docker compose -f docker-compose.local.yml ps # or production.yml
# Restart all services
docker compose -f docker-compose.local.yml restart# Verify credentials in .env
cat .env
# Test connection
docker exec -it wordpress-mysql mysql -u ${MYSQL_USER} -p${MYSQL_PASSWORD}# Fix WordPress permissions (use wordpress-app or wordpress-app-local)
docker exec wordpress-app chown -R www-data:www-data /var/www/htmlExample .env for local development:
DOMAIN=localhost
CADDY_EMAIL=dev@localhost
MYSQL_ROOT_PASSWORD=localroot
MYSQL_DATABASE=wordpress_dev
MYSQL_USER=wpuser
MYSQL_PASSWORD=wppass123
WORDPRESS_DB_HOST=mysql:3306
WORDPRESS_DB_USER=wpuser
WORDPRESS_DB_PASSWORD=wppass123
WORDPRESS_DB_NAME=wordpress_devExample .env for production:
DOMAIN=yourdomain.com
CADDY_EMAIL=admin@yourdomain.com
MYSQL_ROOT_PASSWORD=SuperSecure123!
MYSQL_DATABASE=wordpress_prod
MYSQL_USER=wordpress_user
MYSQL_PASSWORD=AnotherSecure456!
WORDPRESS_DB_HOST=mysql:3306
WORDPRESS_DB_USER=wordpress_user
WORDPRESS_DB_PASSWORD=AnotherSecure456!
WORDPRESS_DB_NAME=wordpress_prodGenerate strong passwords:
openssl rand -base64 321. Backup your current site:
mysqldump -u user -p database > backup.sql
tar czf wp-content.tar.gz /path/to/wp-content2. Start Docker environment:
cp .env.example .env
nano .env # Configure
docker compose -f docker-compose.production.yml up -d
sleep 303. Import database:
docker cp backup.sql wordpress-mysql:/tmp/
docker exec -i wordpress-mysql mysql -u root -p${MYSQL_ROOT_PASSWORD} \
${MYSQL_DATABASE} < /tmp/backup.sql4. Restore files:
docker compose -f docker-compose.production.yml stop wordpress
tar xzf wp-content.tar.gz
docker cp wp-content wordpress-app:/var/www/html/
docker exec wordpress-app chown -R www-data:www-data /var/www/html/wp-content
docker compose -f docker-compose.production.yml start wordpress5. Update URLs in database:
docker exec -it wordpress-mysql mysql -u root -p${MYSQL_ROOT_PASSWORD} ${MYSQL_DATABASE}
UPDATE wp_options SET option_value = 'https://yourdomain.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://yourdomain.com' WHERE option_name = 'home';- Use strong passwords (20+ characters)
- Keep
.envfile secure:chmod 600 .env - Update regularly:
docker compose -f docker-compose.production.yml pull - Enable firewall:
sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable - Regular backups (automate with cron)
- Issues: GitHub Issues
- Docker Docs: https://docs.docker.com/
- Caddy Docs: https://caddyserver.com/docs/
Made with β€οΈ for easy WordPress deployment