Skip to content

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)

ServicePortProtocolPurpose
Nginx HTTP8880HTTPDevelopment access
Nginx HTTPS8443HTTPSSSL access
MySQL3307MySQLDatabase access
Qdrant API6333HTTPVector database
Qdrant gRPC6334gRPCVector database
MCP Server8765HTTPAI integration
phpMyAdmin8081HTTPDB management
Dashboard3000HTTPReact dashboard
Docs5173HTTPVitePress docs

Internal Ports (Docker Network)

ServicePortPurpose
WordPress80HTTP (internal only)
MySQL3306Database connections
Qdrant6333, 6334Vector DB
MCP8765MCP 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.crt

Linux

bash
# Copy to trusted certificates
sudo cp ssl/my-site.localhost.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

Windows

powershell
# Import certificate
Import-Certificate -FilePath ssl\my-site.localhost.crt -CertStoreLocation Cert:\LocalMachine\Root

Wildcard 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.1

Service 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 Qdrant

Network 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 mysql

Load 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 enable

macOS Firewall

bash
# Allow incoming connections for Docker
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /Applications/Docker.app

DNS 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.localhost

Wildcard 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 dnsmasq

Network 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
done

Test SSL

bash
# Check certificate
openssl s_client -connect my-site.localhost:8443

# Verify certificate
openssl x509 -in ssl/my-site.localhost.crt -text -noout

Debug 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-nginx

Network 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:

Released under the MIT License.