A professional Docker-based development environment for running unlimited WordPress sites with Nginx (sites-available/enabled), PHP-FPM, MySQL, and PhpMyAdmin.
Perfect for: agencies, developers managing multiple projects, or anyone running several WordPress sites locally.
- π Unlimited Sites: Simple workflow without editing
docker-compose.yml - π SSL via mkcert: Trusted local HTTPS certificates
- π§ Nginx sites-available/enabled: Professional configuration management
- π Single PHP-FPM Pool: Official WordPress PHP 8.2-FPM image serving all sites
- ποΈ MySQL 8.0: Shared database server (separate database per site)
- π PhpMyAdmin: Web-based MySQL administration
- β‘ Optimized: OPcache, Gzip, FastCGI tuning
- Docker (20.10+) and Docker Compose (2.0+)
- mkcert for local SSL certificates
- Linux/macOS (Windows WSL2 supported)
sudo apt install libnss3-tools
wget -O mkcert https://github.com/FiloSottile/mkcert/releases/latest/download/mkcert-v1.4.4-linux-amd64
chmod +x mkcert
sudo mv mkcert /usr/local/bin/
mkcert -installAdding a new WordPress site involves 5 simple steps:
- Create Nginx config β
nginx/sites-available/yoursite.test.conf - Download WordPress β
sites/yoursite/ - Generate SSL cert β
mkcert yoursite.test - Add to /etc/hosts β
127.0.0.1 yoursite.test - Start containers β
docker-compose up -d
Use the new-site.sh script:
./new-site.shEnter your domain (e.g., mysite.test) and the script will:
- Create Nginx configuration
- Download latest WordPress
- Generate SSL certificates
- Offer to add to /etc/hosts
- Offer to start Docker containers
Visit https://mysite.test and complete the WordPress installation!
Database Setup: Use WordPress installer or PhpMyAdmin to create the database.
# 1. Create Nginx configuration
DOMAIN="mysite.test"
SITE_NAME="mysite"
sed "s/DOMAIN/$DOMAIN/g" nginx/sites-available/site.conf.template > nginx/sites-available/${DOMAIN}.conf
sed -i "s|/var/www/SITE_NAME|/var/www/$SITE_NAME|g" nginx/sites-available/${DOMAIN}.conf
ln -s ../sites-available/${DOMAIN}.conf nginx/sites-enabled/${DOMAIN}.conf
# 2. Download WordPress
mkdir -p sites/$SITE_NAME && cd sites/$SITE_NAME
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz --strip-components=1 && rm latest.tar.gz
cd ../..
# 3. Generate SSL certificate
mkcert -cert-file nginx/ssl/certs/${DOMAIN}.pem \
-key-file nginx/ssl/private/${DOMAIN}-key.pem \
$DOMAIN
# 4. Add to /etc/hosts
echo "127.0.0.1 $DOMAIN" | sudo tee -a /etc/hosts
# 5. Start Docker
docker compose up -d| Service | URL | Credentials |
|---|---|---|
| Your WordPress Sites | https://yoursite.test |
Set during WP installation |
| PhpMyAdmin | http://localhost:8080 |
Username: rootPassword: See .env |
| MySQL (external) | localhost:3306 |
Username: rootPassword: See .env |
wp-docker/
βββ docker-compose.yml # Container orchestration
βββ .env # Environment variables (DB passwords)
βββ new-site.sh # Automated site provisioning β
βββ install-mkcert.sh # mkcert installation helper
βββ manage-sites.sh # Site management utilities
β
βββ nginx/
β βββ nginx.conf # Main Nginx config
β βββ sites-available/ # All site configurations
β β βββ site.conf.template # Template for new sites
β β βββ default.conf # Catch-all/default site
β β βββ *.test.conf # Your site configs
β βββ sites-enabled/ # Symlinks to enabled sites
β β βββ *.test.conf β ../sites-available/
β βββ ssl/
β βββ certs/ # SSL certificates (.pem)
β βββ private/ # SSL private keys (-key.pem)
β
βββ sites/ # WordPress installations
βββ site1/ # Site 1 WordPress files
βββ site2/ # Site 2 WordPress files
βββ ...
When installing WordPress, use these database settings:
- Database Name: Create via PhpMyAdmin or MySQL CLI (e.g.,
mysite_db) - Username:
root(or create dedicated user) - Password: Check
.envfile βDB_ROOT_PASSWORD - Database Host:
mysql - Table Prefix:
wp_
# Connect to MySQL
docker exec -it wp-mysql mysql -u root -p
# Enter password from .env
# Create database and user
CREATE DATABASE mysite_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'mysite_user'@'%' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON mysite_db.* TO 'mysite_user'@'%';
FLUSH PRIVILEGES;
EXIT;- QUICK-SETUP.md - β‘ Fast setup guide (< 5 minutes)
- ARCHITECTURE.md - Technical architecture overview
- SETUP-COMPLETE.md - Post-setup verification
Let's add a site called portfolio.test:
# Run the automated script
./new-site.sh
# Or manually:
DOMAIN="portfolio.test"
sed "s/DOMAIN/$DOMAIN/g" nginx/sites-available/site.conf.template > nginx/sites-available/${DOMAIN}.conf
sed -i "s|/var/www/SITE_NAME|/var/www/portfolio|g" nginx/sites-available/${DOMAIN}.conf
ln -s ../sites-available/${DOMAIN}.conf nginx/sites-enabled/${DOMAIN}.conf
mkdir -p sites/portfolio && cd sites/portfolio
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz --strip-components=1 && rm latest.tar.gz
cd ../..
mkcert -cert-file nginx/ssl/certs/portfolio.test.pem \
-key-file nginx/ssl/private/portfolio.test-key.pem \
portfolio.test
echo "127.0.0.1 portfolio.test" | sudo tee -a /etc/hosts
docker compose up -dVisit https://portfolio.test and install WordPress!
# Start all containers
docker compose up -d
# Stop all containers
docker compose down
# View logs
docker compose logs -f nginx
docker compose logs -f php
# Restart Nginx (after config changes)
docker exec wp-nginx nginx -s reload
# Test Nginx configuration
### Nginx Configuration Error?
docker exec wp-nginx nginx -t
# Access MySQL CLI
docker exec -it wp-mysql mysql -u root -p
# Fix file permissions
sudo chown -R $USER:$USER sites/yoursitemkcert -install# Verify /etc/hosts entry
cat /etc/hosts | grep yoursite.test
# Check Nginx config
docker exec wp-nginx nginx -t
# Check containers are running
docker compose ps# Restart PHP-FPM
docker compose restart php
# Check PHP logs
docker compose logs php# Fix ownership
sudo chown -R $USER:$USER sites/- This setup is for local development only
.envcontains database passwords (never commit to git)- mkcert certificates are trusted locally only
- For production, use proper SSL certificates (Let's Encrypt)
Contributions welcome! Please open an issue or pull request.
MIT License - feel free to use for personal or commercial projects.
| Component | Technology | Purpose |
|---|---|---|
| Web Server | Nginx (Alpine) | Reverse proxy, SSL termination, static files |
| PHP | WordPress Official Image (PHP 8.2-FPM) | WordPress execution |
| Database | MySQL 8.0 | Data storage |
| DB Admin | PhpMyAdmin | Database management UI |
| SSL | mkcert | Local trusted certificates |
| Orchestration | Docker Compose | Container management |
Happy developing! π