Skip to content

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 -1 for SSE streaming, with 300s read/write timeouts
  • n8n proxy: Uses flush_interval -1 for 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:

ports:
  - "127.0.0.1:2368:2368"  # NOT "2368:2368"

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)