# Standalone DERP Relay Server — Seattle VPS # ============================================================================= # Tailscale/Headscale DERP relay for external fallback connectivity. # Serves as region 901 "Seattle VPS" in the headscale derpmap. # # Why standalone (not behind nginx): # The DERP protocol does an HTTP→binary protocol switch inside TLS. # It is incompatible with HTTP reverse proxies. Must handle TLS directly. # # Port layout: # 8444/tcp — DERP relay (direct TLS, NOT proxied through nginx) # 3478/udp — STUN (NAT traversal hints) # # TLS cert: # Issued by Let's Encrypt via certbot DNS challenge (Cloudflare). # Cert path: /etc/letsencrypt/live/derp-sea.vish.gg/ # Renewal hook at /etc/letsencrypt/renewal-hooks/deploy/derp-sea-symlinks.sh # auto-restarts this container after renewal. # # UFW rules required (one-time, already applied): # ufw allow 8444/tcp # DERP TLS # ufw allow 3478/udp # STUN # # DNS: derp-sea.vish.gg → YOUR_WAN_IP (managed by ddns-updater.yaml, unproxied) # ============================================================================= services: derper: image: fredliang/derper:latest container_name: derper restart: unless-stopped ports: - "8444:8444" # DERP TLS — direct, not behind nginx - "3478:3478/udp" # STUN volumes: # Full letsencrypt mount required — live/ contains symlinks into archive/ # mounting only live/ breaks symlink resolution inside the container - /etc/letsencrypt:/etc/letsencrypt:ro environment: - DERP_DOMAIN=derp-sea.vish.gg - DERP_CERT_MODE=manual - DERP_CERT_DIR=/etc/letsencrypt/live/derp-sea.vish.gg - DERP_ADDR=:8444 - DERP_STUN=true - DERP_STUN_PORT=3478 - DERP_HTTP_PORT=-1 # disable plain HTTP, TLS only - DERP_VERIFY_CLIENTS=false # allow any node (headscale manages auth)