Skip to content

Michael7371/multi-wordpress-deployment

Repository files navigation

Multi-WordPress Deployment with Docker Compose

This Docker Compose stack deploys 5 WordPress websites with automatic SSL certificate management using Let's Encrypt and Nginx reverse proxy.

Features

  • 🚀 5 Independent WordPress Sites - Each with its own database and configuration
  • 🔒 Automatic SSL Certificates - Let's Encrypt integration for free SSL certificates
  • 🌐 Nginx Reverse Proxy - Efficient load balancing and SSL termination
  • 🗄️ MySQL 8.0 Database - Consolidated database hosting all WordPress sites
  • 📊 phpMyAdmin - Web-based database management interface
  • 🔧 Easy Configuration - Environment-based configuration
  • 📈 Performance Optimized - Caching, compression, and security headers
  • ⏱️ Kimai Time Tracking - Integrated time tracking system
  • 💾 Hybrid Storage - WordPress core in Docker volumes, user content in bind mounts

Architecture

Internet → Nginx Proxy (80/443) → Let's Encrypt → WordPress Sites → MySQL Database
                                    ↓              ↓
                              Auto Config    SSL Certificates

The stack uses:

  • nginx-proxy: Main reverse proxy with automatic configuration
  • letsencrypt: Manages Let's Encrypt SSL certificates automatically
  • mysql: Consolidated MySQL 8.0 database hosting all WordPress sites
  • kimai: Time tracking system with separate database

Prerequisites

  • Docker and Docker Compose installed
  • Domain names pointing to your server
  • Ports 80 and 443 available

Quick Start

  1. Clone and navigate to the project:

    cd multi-wordpress-deployment
  2. Copy the environment file:

    cp sample.env .env
  3. Edit the environment file:

    nano .env
    Update the following variables:
    
    • LETSENCRYPT_EMAIL - Your email for Let's Encrypt notifications
    • WP1_DOMAIN, WP2_DOMAIN, WP3_DOMAIN, WP4_DOMAIN, WP5_DOMAIN - Your actual domain names
    • MYSQL_ROOT_PASSWORD - Secure MySQL root password
    • Database passwords for each WordPress site
    • Kimai configuration (if using time tracking)
    • Resource limits (WP_MEMORY, WP_CPUS, KIMAI_MEMORY) for your VM specs
  4. Create required directories:

    mkdir -p certs logs/nginx vhost.d html
  5. Start the stack:

    docker compose up -d
  6. Check the status:

    docker compose ps

Configuration

Environment Variables

Variable Description Example
LETSENCRYPT_EMAIL Email for Let's Encrypt notifications admin@example.com
MYSQL_ROOT_PASSWORD MySQL root password secure_password_123
WP1_DOMAIN Domain for WordPress site 1 site1.example.com
WP1_DB_NAME Database name for site 1 wordpress1
WP1_DB_USER Database user for site 1 wp1_user
WP1_DB_PASSWORD Database password for site 1 wp1_password
WP1_TABLE_PREFIX WordPress table prefix for site 1 wp1_
WP5_DOMAIN Domain for WordPress site 5 site5.example.com
WP5_DB_NAME Database name for site 5 wordpress5
WP5_DB_USER Database user for site 5 wp5_user
WP5_DB_PASSWORD Database password for site 5 wp5_password
WP5_TABLE_PREFIX WordPress table prefix for site 5 wp5_
KIMAI_DOMAIN Domain for Kimai time tracking kimai.example.com
KIMAI_DB_NAME Database name for Kimai kimai
KIMAI_DB_USER Database user for Kimai kimai_user
KIMAI_DB_PASSWORD Database password for Kimai kimai_password

Domain Configuration

Make sure your domain names point to your server's IP address:

# Example DNS records
site1.example.com.    A    YOUR_SERVER_IP
site2.example.com.    A    YOUR_SERVER_IP
site3.example.com.    A    YOUR_SERVER_IP
site4.example.com.    A    YOUR_SERVER_IP
site5.example.com.    A    YOUR_SERVER_IP
kimai.example.com.    A    YOUR_SERVER_IP
pma.example.com.      A    YOUR_SERVER_IP

Services

WordPress Sites

  • wordpress1 - First WordPress site
  • wordpress2 - Second WordPress site
  • wordpress3 - Third WordPress site
  • wordpress4 - Fourth WordPress site
  • wordpress5 - Fifth WordPress site

Databases

  • mysql - Consolidated MySQL 8.0 database hosting all WordPress sites and Kimai

Infrastructure

  • nginx-proxy - Nginx reverse proxy with automatic configuration
  • letsencrypt - Automatic SSL certificate management
  • kimai - Time tracking system
  • phpmyadmin - Database management interface

Access URLs

After deployment, you can access:

  • WordPress Site 1: https://site1.example.com
  • WordPress Site 2: https://site2.example.com
  • WordPress Site 3: https://site3.example.com
  • WordPress Site 4: https://site4.example.com
  • WordPress Site 5: https://site5.example.com
  • Kimai Time Tracking: https://kimai.example.com
  • phpMyAdmin: https://pma.example.com

SSL Certificates

SSL certificates are automatically managed by Let's Encrypt:

  • Certificates are automatically renewed
  • HTTP traffic is redirected to HTTPS
  • HSTS headers are enabled for security

Security Features

  • Rate Limiting - Protection against brute force attacks
  • Security Headers - XSS protection, content type sniffing prevention
  • SSL/TLS - Modern cipher suites and protocols
  • Isolated Networks - Each service runs in its own network namespace

Backup and Restore

Automated Backup System

The deployment includes comprehensive backup and restore scripts:

# Navigate to deployment directory
cd multi-wordpress-deployment

# Run manual backup
./wp-backup.sh

# Restore specific site
./wp-restore.sh restore wp3 /var/backups/wordpress/wordpress_wp3_20251026_223848.tar.gz files

# Restore database only
./wp-restore.sh restore wp3 /var/backups/wordpress/wordpress_wp3_20251026_223848.tar.gz database

# Full system restore (all databases)
./wp-restore.sh restore wp3 /var/backups/wordpress/wordpress_wp3_20251026_223848.tar.gz full-db

# Setup automated backups
./setup-backup-cron.sh -d  # Daily backups

What Gets Backed Up

  • Individual WordPress Databases - Each site's database separately
  • Full Database Backup - Complete system backup including all databases
  • WordPress Files - Plugins, themes, uploads (bind-mounted directories)
  • Kimai Data - Time tracking data and configuration
  • Configuration Files - docker-compose.yml, .env, SSL certificates
  • Docker Volumes - MySQL data, Kimai data

Storage Architecture

  • WordPress Core - Stored in Docker volumes (wp1_data, wp2_data, etc.)
  • User Content - Plugins, themes, uploads stored in bind-mounted directories (wp/wp1/, wp/wp2/, etc.)
  • Easy Backup - User content directly accessible for backup and restore

Logs

# View Nginx logs
docker compose logs nginx-proxy

# View WordPress logs
docker compose logs wordpress1
docker compose logs wordpress2
docker compose logs wordpress3
docker compose logs wordpress4
docker compose logs wordpress5

# View Kimai logs
docker compose logs kimai

# View MySQL logs
docker compose logs mysql

Troubleshooting

SSL Certificate Issues

# Check Let's Encrypt logs
docker compose logs letsencrypt

# Force certificate renewal
docker compose restart letsencrypt

Database Connection Issues

# Check database status
docker compose ps mysql

# Connect to database
docker compose exec mysql mysql -u root -p

Nginx Issues

# Check Nginx configuration
docker compose exec nginx-proxy nginx -t

# Reload Nginx configuration
docker compose exec nginx-proxy nginx -s reload

Resource Management

The stack is optimized for a 2-core 4GB VM with the following resource allocation:

Memory Allocation (Total: ~3.2GB)

  • WordPress containers: 512MB each (5 × 512MB = 2.5GB)
  • MySQL database: 1GB
  • Kimai: 512MB
  • Infrastructure: ~200MB (nginx, letsencrypt, phpmyadmin)
  • System overhead: ~800MB reserved

CPU Allocation (Total: 2 cores)

  • WordPress containers: 0.5 cores each (5 × 0.5 = 2.5 cores)
  • MySQL database: 0.5 cores
  • Kimai: 0.25 cores
  • Infrastructure: Minimal CPU usage

Log Management

  • Log retention: 10MB per container, max 3 files
  • Automatic rotation: Prevents disk space issues

Performance Optimization

The stack includes several performance optimizations:

  • Gzip Compression - Reduces bandwidth usage
  • Static File Caching - Improves load times
  • Database Optimization - MySQL tuned for WordPress
  • PHP Optimization - Increased memory and upload limits
  • Resource Limits - Prevents container resource exhaustion

Scaling

To add more WordPress sites:

  1. Add new services to docker-compose.yml
  2. Add corresponding environment variables to .env
  3. Update DNS records
  4. Restart the stack

Troubleshooting

Common Issues

  1. 4th WordPress site not accessible:

    # Run the debug script
    ./debug.sh
    
    # Check if docker-gen generated the config
    docker-compose exec nginx-proxy cat /etc/nginx/conf.d/default.conf
    
    # Restart docker-gen
    docker-compose restart docker-gen
  2. SSL certificate issues:

    # Check Let's Encrypt logs
    docker-compose logs letsencrypt
    
    # Verify DNS propagation
    nslookup your-domain.com
  3. Resource exhaustion:

    # Check resource usage
    docker stats
    
    # Adjust limits in .env file
    WP_MEMORY=256M  # Reduce if needed
    DB_MEMORY=256M  # Reduce if needed
  4. Container startup issues:

    # Check all logs
    docker-compose logs
    
    # Restart specific service
    docker-compose restart [service-name]

Support

For issues and questions:

  1. Run the debug script: ./debug.sh
  2. Check the logs: docker-compose logs [service-name]
  3. Verify DNS resolution
  4. Ensure ports 80 and 443 are open
  5. Check firewall settings
  6. Review resource limits in .env file

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

wordpress deployment for public websites

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published