A comprehensive Docker-based platform for managing multiple WordPress websites with automated CI/CD deployment, monitoring, and backup systems.
- GitHub Actions integration for automated deployments
- Multi-environment support (development, staging, production)
- Automated testing and security scanning
- Zero-downtime deployments with rollback capabilities
- Docker Compose orchestration for easy management
- Nginx reverse proxy with SSL termination
- MySQL 8.0 database with optimized configuration
- Redis caching for performance optimization
- Let's Encrypt automated SSL certificates
- Automated daily backups with configurable retention
- Health monitoring with Slack notifications
- Performance monitoring and alerting
- SSL certificate expiration tracking
- Security scanning with vulnerability detection
- One-click website addition through GitHub Actions
- Automated configuration generation
- Pull request workflow with validation
- Documentation auto-generation
| Website | Domain | Type | Status |
|---|---|---|---|
| AirArom | airarom.ma | WordPress | ✅ Active |
| ElectroRomanos | electroromanos.ma | WordPress | ✅ Active |
| FreshExpress | freshexpress.ma | WordPress | ✅ Active |
| Sabeel Agency | sabeel.agency | WordPress | ✅ Active |
| Sabeel Academy | sabeelacademy.ma | WordPress | ✅ Active |
| Sumo | sumo.ma | WordPress | ✅ Active |
| Yves Morel | yvesmorel.ma | WordPress | ✅ Active |
| Zonemation | zonemation.com | WordPress | ✅ Active |
| Oumnia Rental Cars | oumniarentalcars.com | Static | ✅ Active |
📦 WP/ ├── 📄 docker-compose.yml # Main Docker Compose configuration ├── 📄 .env # Environment variables (EDIT THIS!) ├── 📂 dockerfiles/ │ └── 📄 Dockerfile.wordpress # WordPress container configuration ├── 📂 nginx/ │ ├── 📄 nginx.conf # Main Nginx configuration │ ├── 📄 static.conf # Static site configuration │ └── 📂 conf.d/ │ └── 📄 default.conf # Site-specific configurations ├── 📂 mysql/ │ └── 📂 init/ │ └── 📄 01-create-databases.sql ├── 📂 scripts/ │ ├── 📄 deploy.sh # Main deployment script │ ├── 📄 server-setup.sh # Server preparation script │ └── 📄 backup.sh # Backup and restore script ├── 📂 backups/ # Backup storage ├── 📂 logs/ # Application logs └── 📂 ssl/ # SSL certificates - Docker and Docker Compose installed
- GitHub account with repository access
- VPS or dedicated server with root access
- Domain names with DNS access
# Clone the repository git clone https://github.com/your-username/wordpress-multisite.git cd wordpress-multisite # Copy and configure environment file cp .env.example .env # Edit .env with your database passwords and configuration# Set up GitHub repository (replace with your details) chmod +x .github/scripts/setup-repository.sh ./.github/scripts/setup-repository.sh your-username wordpress-multisiteAdd the following secrets to your GitHub repository (Settings → Secrets → Actions):
# Production Environment PRODUCTION_HOST=your-server-ip PRODUCTION_USER=your-ssh-username PRODUCTION_PRIVATE_KEY=your-ssh-private-key PRODUCTION_PATH=/var/www/wordpress-multisite PRODUCTION_ENV=your-complete-env-file-content # Notifications SLACK_WEBHOOK=your-slack-webhook-url# Push to trigger deployment git add . git commit -m "Initial setup" git push origin main # Monitor deployment in GitHub Actions| Document | Description |
|---|---|
| Setup Guide | Complete server setup and configuration |
| Future Branching Strategy | Development workflow for scaling |
| Complete Backup Strategy | Comprehensive backup and recovery guide |
| Backblaze B2 Integration | Cloud backup strategy and cost analysis |
| Deployment Ready Guide | Production deployment checklist |
# Database Configuration MYSQL_ROOT_PASSWORD=your_secure_root_password # Website Configurations (example) AIRAROM_DB_NAME=airarom_wp AIRAROM_DB_USER=airarom_user AIRAROM_DB_PASSWORD=secure_password # Environment Settings ENVIRONMENT=production WP_DEBUG=false WP_FORCE_SSL_ADMIN=true # Performance Settings PHP_MEMORY_LIMIT=512M PHP_MAX_EXECUTION_TIME=300# Staging-specific configuration ENVIRONMENT=staging WP_DEBUG=true SSL_STAGING=true # Staging databases with different names AIRAROM_DB_NAME=staging_airarom_wp # ... other staging configurations# Deploy to production ./scripts/deploy-enhanced.sh deploy production # Deploy to staging ./scripts/deploy-enhanced.sh deploy staging # Create manual backup ./scripts/deploy-enhanced.sh backup production # Check system status ./scripts/deploy-enhanced.sh status production # Rollback deployment ./scripts/deploy-enhanced.sh rollback production # Manage SSL certificates ./scripts/deploy-enhanced.sh ssl install# Start all services docker-compose up -d # Stop all services docker-compose down # View logs docker-compose logs -f [service-name] # Check service status docker-compose psEach WordPress site has its own database:
- electromanos_wp → electromanos.ma
- freshexpress_wp → freshexpress.ma
- sabeel_wp → sabeel.agency
- sabeelacademy_wp → sabeelacademy.ma
- sumo_wp → sumo.ma
- yvesmorel_wp → yvesmorel.ma
- zonemation_wp → zonemation.com
Each site includes:
- ✅ PHP 8.2 with optimized extensions
- ✅ Redis object caching
- ✅ ImageMagick support
- ✅ WP-CLI integration
- ✅ Security headers
- ✅ Performance optimization
- 🔒 UFW firewall configured
- 🔒 Fail2ban protection
- 🔒 SSL/TLS certificates
- 🔒 Security headers
- 🔒 Rate limiting
- 🔒 Isolated containers
- Go to GitHub Actions → "Add New Website" workflow
- Fill in details:
- Website name:
newsite - Domain:
newsite.com - Type:
wordpressorstatic
- Website name:
- Review the generated pull request
- Add environment variables to your
.envfile - Configure DNS to point to your server
- Merge and deploy
- Generate SSL certificate
# Create feature branch git checkout -b matt/add-website-newsite # Create website structure mkdir -p newsite.com/public_html # Update Docker Compose configuration# Update Nginx configuration# Update deployment scripts# Commit and create PR git add . git commit -m "Add new website: newsite.com" git push origin matt/add-website-newsite gh pr create --title "Add new website: newsite.com"- Website availability monitoring (every hour during business hours)
- Database connectivity checks
- SSL certificate expiration alerts (30-day warning)
- System resource monitoring (CPU, memory, disk)
- Container health status checks
| Backup Type | Frequency | Retention | Includes |
|---|---|---|---|
| Daily Auto | 2 AM UTC | 30 days | All WordPress databases |
| Emergency | Before deployments | 90 days | Database snapshots |
| Manual | On-demand | 30 days | Database + metadata |
Note: Website files backup and Backblaze B2 cloud storage documented for future implementation.
- Slack integration for deployment status
- Email alerts for critical issues
- GitHub notifications for workflow results
- Vulnerability scanning with Trivy
- Sensitive file detection
- Docker security best practices
- SSL certificate management
- Failed login attempt monitoring
- Environment-specific credentials
- Encrypted secrets storage
- Regular security updates
- File permission management
- Network isolation with Docker networks
Each domain is configured in /nginx/conf.d/default.conf:
server{listen80;server_name yourdomain.com www.yourdomain.com;location / {proxy_passhttp://container_name:80; # ... proxy headers}}# Automatic certificate generation ./scripts/deploy.sh ssl # Manual certificate installation certbot certonly --standalone -d yourdomain.com -d www.yourdomain.comServices won't start:
# Check logs ./scripts/deploy.sh logs # Restart services ./scripts/deploy.sh restartDatabase connection errors:
# Check MySQL status docker-compose logs mysql # Restart MySQL docker-compose restart mysqlWebsite not accessible:
# Check Nginx status docker-compose logs nginx # Verify domain DNS nslookup yourdomain.com # Check firewall sudo ufw statusSSL certificate issues:
# Renew certificates certbot renew # Check certificate validity openssl x509 -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem -text -nooutOptimize MySQL:
# Edit MySQL configuration# Add to docker-compose.yml under mysql service command: --innodb-buffer-pool-size=512M --max-connections=200Enable Redis caching:
# Redis is already configured - verify in WordPress admin# Install Redis Object Cache plugin if not presentMonitor disk space:
df -h docker system prune -f # Clean unused Docker dataTo add more sites:
- Add new service in
docker-compose.yml - Add database configuration in
.env - Add Nginx virtual host configuration
- Update backup script
Increase resources in docker-compose.yml:
services: mysql: deploy: resources: limits: memory: 2Greservations: memory: 1G- Change all default passwords in
.env - Configure UFW firewall
- Install SSL certificates
- Enable fail2ban
- Update all WordPress sites and plugins
- Configure automated backups
- Monitor logs regularly
- Keep Docker images updated
- Nginx:
/opt/wordpress-docker/logs/nginx/ - Docker:
/var/lib/docker/containers/ - System:
/var/log/
# Container shell access docker-compose exec wordpress_container_name bash # Database shell access docker-compose exec mysql mysql -uroot -p # View container logs docker logs container_name # System resource monitoring htop iotop netstat -tulpn# Stop all services ./scripts/deploy.sh stop # Restore from latest backup ./scripts/backup.sh restore /path/to/latest/backup # Start services ./scripts/deploy.sh startThis project is licensed under the MIT License. See LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
- Always backup before making changes
- Test deployments in staging environment first
- Monitor resource usage regularly
- Keep security updates current
- Document any custom modifications
🎯 Next Steps:
- Configure domain DNS settings
- Install and configure SSL certificates
- Set up monitoring and alerts
- Optimize performance settings
- Configure regular security updates