Networking & SSL
Network architecture, SSL/TLS configuration, and domain routing for multi-project WordPress development.
Network Overview
%%{init: {'theme':'neutral'}}%%
graph TB
Browser[Browser<br/>:8443] -->|HTTPS| Nginx
Claude[Claude Desktop] -->|HTTP| MCP
subgraph "Host Machine :8443"
Nginx[Nginx Proxy<br/>SSL Termination]
end
subgraph "Docker Network 172.25.0.0/16"
Nginx -->|HTTP :80| WP1[WordPress<br/>my-site]
Nginx -->|HTTP :80| WP2[WordPress<br/>client-site]
Nginx -->|HTTP :80| WP3[WordPress<br/>demo]
WP1 -->|:3306| MySQL
WP2 -->|:3306| MySQL
WP3 -->|:3306| MySQL
MCP[MCP Server<br/>:8765] -->|:6333| Qdrant
end
Port Mapping
External Ports (Host Machine)
| Service | Port | Protocol | Purpose |
|---|---|---|---|
| Nginx HTTP | 8880 | HTTP | Development access |
| Nginx HTTPS | 8443 | HTTPS | SSL access |
| MySQL | 3307 | MySQL | Database access |
| Qdrant API | 6333 | HTTP | Vector database |
| Qdrant gRPC | 6334 | gRPC | Vector database |
| MCP Server | 8765 | HTTP | AI integration |
| phpMyAdmin | 8081 | HTTP | DB management |
| Dashboard | 3000 | HTTP | React dashboard |
| Docs | 5173 | HTTP | VitePress docs |
Internal Ports (Docker Network)
| Service | Port | Purpose |
|---|---|---|
| WordPress | 80 | HTTP (internal only) |
| MySQL | 3306 | Database connections |
| Qdrant | 6333, 6334 | Vector DB |
| MCP | 8765 | MCP protocol |
Domain Routing
Nginx Configuration
Main config at services/nginx/nginx.conf:
nginx
http {
# Upstream definitions
upstream wordpress-my-site {
server wdg-wp-my-site:80;
}
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Include project configs
include /etc/nginx/sites-enabled/*.conf;
}Per-Project Configuration
services/nginx/sites-enabled/my-site.conf:
nginx
server {
listen 443 ssl http2;
server_name my-site.localhost;
ssl_certificate /etc/nginx/ssl/my-site.localhost.crt;
ssl_certificate_key /etc/nginx/ssl/my-site.localhost.key;
root /var/www/html;
index index.php;
# WordPress permalinks
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP handling
location ~ \.php$ {
proxy_pass http://wdg-wp-my-site;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
# Static files
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Deny access to sensitive files
location ~ /\. {
deny all;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
}
# HTTP to HTTPS redirect
server {
listen 80;
server_name my-site.localhost;
return 301 https://$server_name$request_uri;
}SSL/TLS Configuration
Certificate Generation
Self-signed certificates are auto-generated:
bash
# Generate certificate for project
wdg ssl generate my-site
# Manual generation
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/my-site.localhost.key \
-out ssl/my-site.localhost.crt \
-subj "/CN=my-site.localhost"Certificate Trust
macOS
bash
# Add to keychain
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain \
ssl/my-site.localhost.crtLinux
bash
# Copy to trusted certificates
sudo cp ssl/my-site.localhost.crt /usr/local/share/ca-certificates/
sudo update-ca-certificatesWindows
powershell
# Import certificate
Import-Certificate -FilePath ssl\my-site.localhost.crt -CertStoreLocation Cert:\LocalMachine\RootWildcard Certificates
For multiple subdomains:
bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/wildcard.localhost.key \
-out ssl/wildcard.localhost.crt \
-subj "/CN=*.localhost" \
-addext "subjectAltName=DNS:*.localhost,DNS:localhost"Docker Networking
Network Configuration
yaml
networks:
wdg-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.25.0.0/16
gateway: 172.25.0.1Service Discovery
Containers resolve each other by service name:
php
// From WordPress container
$db_host = 'mysql'; // Resolves to MySQL container
$vector_db = 'qdrant:6333'; // Resolves to QdrantNetwork Inspection
bash
# View network details
docker network inspect wdg-network
# List connected containers
docker network inspect wdg-network --format='{{json .Containers}}' | jq
# Test connectivity
docker exec wdg-wp-my-site ping -c 3 mysqlLoad Balancing
Multiple Project Instances
For high-traffic projects:
nginx
upstream wordpress-my-site {
least_conn; # Load balancing method
server wdg-wp-my-site-1:80;
server wdg-wp-my-site-2:80;
server wdg-wp-my-site-3:80;
}Health Checks
nginx
upstream wordpress-my-site {
server wdg-wp-my-site:80 max_fails=3 fail_timeout=30s;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
}WebSocket Support
For hot-reload and real-time features:
nginx
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}Custom Headers
WordPress HTTPS Detection
nginx
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;Security Headers
nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;Performance Optimization
Caching
nginx
# Browser caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# FastCGI cache
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";Compression
nginx
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;Connection Tuning
nginx
keepalive_timeout 65;
keepalive_requests 100;
client_max_body_size 64M;Firewall Configuration
UFW (Linux)
bash
# Allow required ports
sudo ufw allow 8443/tcp # HTTPS
sudo ufw allow 8880/tcp # HTTP
sudo ufw allow 3307/tcp # MySQL (if external access needed)
# Enable firewall
sudo ufw enablemacOS Firewall
bash
# Allow incoming connections for Docker
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /Applications/Docker.appDNS Configuration
Local Development
Add to /etc/hosts:
127.0.0.1 my-site.localhost
127.0.0.1 client-site.localhost
127.0.0.1 demo.localhostWildcard DNS (dnsmasq)
bash
# Install dnsmasq
brew install dnsmasq # macOS
# apt-get install dnsmasq # Linux
# Configure wildcard
echo "address=/.localhost/127.0.0.1" >> /usr/local/etc/dnsmasq.conf
# Restart
sudo brew services restart dnsmasqNetwork Troubleshooting
Check Port Availability
bash
# macOS/Linux
lsof -i :8443
# Check all WDG ports
for port in 8880 8443 3307 6333 8765; do
lsof -i :$port
doneTest SSL
bash
# Check certificate
openssl s_client -connect my-site.localhost:8443
# Verify certificate
openssl x509 -in ssl/my-site.localhost.crt -text -nooutDebug Nginx
bash
# Test configuration
docker exec wdg-nginx nginx -t
# Reload configuration
docker exec wdg-nginx nginx -s reload
# View error log
docker logs wdg-nginxNetwork Connectivity
bash
# Test from container
docker exec wdg-wp-my-site curl -I https://my-site.localhost:8443
# Test database connection
docker exec wdg-wp-my-site mysql -h mysql -u wordpress -pwordpress -e "SELECT 1"See Also: