Networking
Traffic Flow
graph LR
Internet((Internet)) -->|"HTTPS :443"| Caddy["Caddy"]
Caddy --> blogs["Ghost x3<br>:2368-2370"]
Caddy --> mcp["Ghost MCP<br>:3002"]
Caddy --> n8n["n8n<br>:5678"]
Caddy --> dozzle["Dozzle<br>:9999"]
Caddy --> glances["Glances<br>:61208"]
Caddy --> docs["Docs<br>:8082"]
Public Domains
All domains resolve to 5.78.46.18. TLS is handled automatically by Caddy via Let's Encrypt.
| Domain | Backend | Port | Purpose |
|---|---|---|---|
| blog.cam4.camlab.dev | ghost-cam4 | 2368 | Cam4 blog |
| blog.cam4models.camlab.dev | ghost-cam4models | 2369 | Cam4Models blog |
| blog.cam4pays.camlab.dev | ghost-cam4pays | 2370 | Cam4Pays blog |
| mcp.casper.camlab.dev | ghost-mcp | 3002 | Ghost MCP server (SSE-compatible) |
| automate.camlab.dev | n8n | 5678 | n8n workflow automation |
| dozzle.camlab.dev | dozzle | 9999 | Container log viewer |
| glances.camlab.dev | glances | 61208 | System resource monitor |
| docs.camlab.dev | docs | 8082 | Infrastructure documentation (MkDocs) |
Note: The n8n URL is automate.camlab.dev, not n8n.camlab.dev — Chrome flags the n8n subdomain as potentially malicious.
DNS
All DNS records are A records pointing to 5.78.46.18, managed in the camlab.dev domain registrar.
Caddy Configuration
Caddy runs as a system service (not containerized):
# Config location
/etc/caddy/Caddyfile
# Reload after changes
sudo systemctl reload caddy
# Check status
sudo systemctl status caddy
# View logs
sudo journalctl -u caddy --since "1 hour ago"
Reference copy of the Caddyfile is also in the repo at camlab.dev/caddy/Caddyfile.
Key Caddy Settings
- Ghost MCP proxy: Uses
flush_interval -1for SSE streaming, with 300s read/write timeouts - n8n proxy: Uses
flush_interval -1for WebSocket support, plus security headers - Blog proxies: Simple reverse proxy, no special settings needed
CORS (Ghost MCP only)
The Ghost MCP endpoint has permissive CORS headers to support MCP client connections:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, Accept
Docker Network
All containers share a single bridge network: camlab_network
Internal Hostnames
Containers reach each other by container name:
| From | To | URL |
|---|---|---|
| Runners | Ghost MCP | http://ghost-mcp:3002/<token> |
| Runners | Reddit MCP | http://reddit-mcp:8080/sse |
| Runners | Playwright MCP | http://playwright-mcp:8931/mcp |
| Runners | Runware MCP | http://runware-mcp:8081/mcp |
| Runners | Twitter MCP | http://twitter-mcp:8081/mcp |
| Runners | Stock Images MCP | http://stockimages-mcp:8000/mcp |
| Runners | Memes MCP | http://memes-mcp:3000/mcp |
| Ghost instances | MySQL | mysql:3306 |
| n8n | Docker socket | /var/run/docker.sock (bind mount) |
Port Binding
All container ports bind to 127.0.0.1 only:
This ensures no container port is accessible from the internet directly — only through Caddy.
Firewall (UFW)
Only 3 ports open externally:
| Port | Service |
|---|---|
| 22 | SSH |
| 80 | HTTP (Caddy / ACME) |
| 443 | HTTPS (Caddy) |