Skip to main content

Network Architecture

Complete network topology for RavenmaskOS.


Overview

RavenmaskOS uses a multi-layer networking approach:

LayerTechnologyPurpose
DNSAWS Route 53Public DNS for *.ravenhelm.dev
Remote AccessTailscaleSecure mesh VPN between machines
EdgeTraefikReverse proxy, TLS termination
ContainerDocker BridgeInternal service communication
WebRTCCoturnTURN relay for voice services

Architecture Diagram

                                    INTERNET


┌───────────────────────────────┐
│ Route 53 DNS │
│ *.ravenhelm.dev │
│ │ │
│ ▼ │
│ 67.198.117.118 │
│ (Public IP) │
└───────────────────────────────┘


┌───────────────────────────────────────────────────────────────────────────┐
│ ODIN │
│ (Mac Mini M4 Pro) │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Tailscale │ │
│ │ 100.115.101.81 │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Mesh VPN: ravenmask (100.104.134.77), iphone (100.96.122.61)│ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Traefik │ │
│ │ :80 → :443 │ │
│ │ TLS Termination │ │
│ │ Let's Encrypt via Route 53 DNS-01 │ │
│ │ │ │
│ │ Routers: norns.ravenhelm.dev → norns-agent:8000 │ │
│ │ gitlab.ravenhelm.dev → gitlab:8080 │ │
│ │ auth.ravenhelm.dev → zitadel:8080 │ │
│ │ ... │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ravenhelm_net │ │
│ │ (Docker Bridge) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ postgres │ │ redis │ │ norns │ │ livekit │ │ gitlab │ │ │
│ │ │ :5432 │ │ :6379 │ │ :8000 │ │ :7880 │ │ :8080 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ ... (45+ containers) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Coturn │ │
│ │ (network_mode: host) │ │
│ │ STUN/TURN :3478, Media Relay :49152-49200 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└───────────────────────────────────────────────────────────────────────────┘

DNS Configuration

Route 53

All *.ravenhelm.dev records point to odin's public IP:

RecordTypeValue
*.ravenhelm.devA67.198.117.118
ravenhelm.devA67.198.117.118

Subdomains

SubdomainServiceNotes
authZitadelIdentity provider
nornsNorns AgentAI platform
bifrostBifrost AdminMCP gateway UI
bifrost-apiBifrost APIMCP gateway API
gitlabGitLab CESource control
registryGitLab RegistryContainer images
grafanaGrafanaObservability
n8nn8nAutomation
voiceVoice GatewayWeb voice UI
telephonyTelephonyPhone voice
livekitLiveKitWebRTC server
langfuseLangfuseLLM tracing
dashboardHomepageService dashboard
haHome AssistantSmart home
homebridgeHomebridgeHomeKit bridge
vaultOpenBaoSecrets (planned)

TLS Certificates

Traefik automatically obtains and renews certificates via Let's Encrypt DNS-01 challenge:

certificatesResolvers:
letsencrypt:
acme:
email: nate@ravenhelm.dev
storage: /certs/acme.json
dnsChallenge:
provider: route53

Required AWS credentials:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_HOSTED_ZONE_ID

Tailscale Mesh VPN

Secure remote access between machines:

NodeTailscale IPOSPurpose
odin100.115.101.81macOSApp server
ravenmask100.104.134.77macOSWorkstation
iphone172100.96.122.61iOSMobile

Access Patterns

# SSH to odin via Tailscale
ssh ravenhelm@100.115.101.81

# SSH via hostname (if MagicDNS enabled)
ssh ravenhelm@odin

MagicDNS

Tailscale provides automatic DNS for connected devices at *.ravenhelm.ts.net.


Docker Networking

ravenhelm_net

All containers run on a shared bridge network:

# Create network (one-time)
docker network create ravenhelm_net

# List connected containers
docker network inspect ravenhelm_net | jq '.[0].Containers | keys[]'

Container DNS

Containers can reach each other by name:

# From any container
curl http://docs/AI-ML-Platform/norns-agent:8000/health
curl http://postgres:5432
curl http://docs/infrastructure/redis:6379

Port Exposure

Most services are internal-only, accessed via Traefik. Key external ports:

PortServiceProtocol
80TraefikHTTP (redirects to 443)
443TraefikHTTPS
2222GitLab SSHSSH
3478CoturnSTUN/TURN
5349CoturnTURNS (TLS)
7881LiveKitWebRTC TCP
50000-50100LiveKitWebRTC UDP
49152-49200CoturnTURN relay UDP

Routing Rules

Traefik Router Pattern

Services are exposed via Docker labels:

labels:
- "traefik.enable=true"
- "traefik.http.routers.myservice.rule=Host(\`myservice.ravenhelm.dev\`)"
- "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls.certresolver=letsencrypt"
- "traefik.http.services.myservice.loadbalancer.server.port=8000"

Path-Based Routing

Some services use path prefixes:

# Voice Platform
- "traefik.http.routers.voice-api.rule=Host(\`voice.ravenhelm.dev\`) && PathPrefix(\`/api\`)"
- "traefik.http.routers.voice-frontend.rule=Host(\`voice.ravenhelm.dev\`)"

Dynamic Configuration

For services that need special handling (h2c, headers):

# ~/ravenhelm/data/traefik/config/dynamic/zitadel.yml
http:
routers:
zitadel:
rule: "Host(\`auth.ravenhelm.dev\`)"
service: zitadel
tls:
certResolver: letsencrypt

services:
zitadel:
loadBalancer:
passHostHeader: true
servers:
- url: "h2c://zitadel:8080" # gRPC-web support

Firewall

macOS Firewall (Odin)

# Allow incoming connections for key services
# Managed via System Preferences > Security > Firewall

Router Port Forwarding

External PortInternal PortService
8080Traefik HTTP
443443Traefik HTTPS
22222222GitLab SSH
34783478Coturn STUN
78817881LiveKit TCP
50000-5010050000-50100LiveKit UDP

Troubleshooting

DNS Resolution

# Check public DNS
dig +short norns.ravenhelm.dev

# Check from container
docker exec traefik nslookup norns-agent

TLS Issues

# Check certificate
echo | openssl s_client -servername norns.ravenhelm.dev \
-connect norns.ravenhelm.dev:443 2>/dev/null | \
openssl x509 -noout -dates

# View ACME log
docker logs traefik 2>&1 | grep -i acme

Container Connectivity

# Test internal DNS
docker exec norns-agent nslookup postgres

# Test internal connectivity
docker exec norns-agent curl -f http://postgres:5432 || echo "No HTTP (expected)"

# Verify network membership
docker network inspect ravenhelm_net | jq '.[0].Containers'

Tailscale Connectivity

# Check status
tailscale status

# Ping remote node
tailscale ping odin

# Debug connectivity
tailscale netcheck

See Also

  • [[Infrastructure/Traefik]] - Detailed Traefik configuration
  • [[Voice-Platform/Coturn]] - TURN relay setup
  • [[DevOps/Docker-Colima]] - Container runtime