deploy: Docker Compose stack with Caddy + Cloudflare TLS
Full production stack via docker compose:
- Caddy reverse proxy with Cloudflare DNS-01 TLS certs
- warzone-server (featherChat API + web UI)
- wzp-relay (QUIC audio SFU)
- wzp-web (browser WS ↔ QUIC bridge)
Architecture:
Internet → Caddy (443/TLS) → voip.manko.yoga
/* → warzone-server:7700
/audio/* → wzp-web:8080
Files:
- docker-compose.yml: main stack (4 services)
- docker-compose.ipv6.yml: IPv6 overlay
- Caddyfile: Cloudflare DNS challenge + reverse proxy
- Dockerfile.server: featherChat multi-stage build
- Dockerfile.wzp: wzp-relay + wzp-web multi-stage build
- .env.example: DNS records for dev/staging/prod
- test-stack.sh: smoke test (8 checks)
- .dockerignore: excludes target/, .git/, etc.
Deployment targets:
dev: 172.16.81.135
ipv6: 2a0d:3344:692c:2500:14f2:5885:d73c:b0a1
prod: 63.250.54.239 / 2602:ff16:9:0:1:3d9:0:1
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
58
warzone/deploy/docker/test-stack.sh
Executable file
58
warzone/deploy/docker/test-stack.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
HOST="${1:-voip.manko.yoga}"
|
||||
SCHEME="${2:-https}"
|
||||
|
||||
echo "=== featherChat Stack Test ==="
|
||||
echo "Host: $HOST ($SCHEME)"
|
||||
echo ""
|
||||
|
||||
# 1. Web UI
|
||||
echo -n "1. Web UI (GET /)... "
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SCHEME://$HOST/")
|
||||
[ "$STATUS" = "200" ] && echo "OK ($STATUS)" || echo "FAIL ($STATUS)"
|
||||
|
||||
# 2. API health
|
||||
echo -n "2. API health... "
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SCHEME://$HOST/v1/health")
|
||||
[ "$STATUS" = "200" ] && echo "OK ($STATUS)" || echo "FAIL ($STATUS)"
|
||||
|
||||
# 3. WASM module
|
||||
echo -n "3. WASM module... "
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SCHEME://$HOST/wasm/warzone_wasm.js")
|
||||
[ "$STATUS" = "200" ] && echo "OK ($STATUS)" || echo "FAIL ($STATUS)"
|
||||
|
||||
# 4. WZP relay config
|
||||
echo -n "4. WZP relay config... "
|
||||
RELAY=$(curl -s "$SCHEME://$HOST/v1/wzp/relay-config")
|
||||
echo "$RELAY" | grep -q "relay_addr" && echo "OK ($(echo $RELAY | python3 -c 'import sys,json; print(json.load(sys.stdin).get("relay_addr","?"))' 2>/dev/null))" || echo "FAIL"
|
||||
|
||||
# 5. Audio bridge (wzp-web via Caddy /audio path)
|
||||
echo -n "5. Audio bridge (GET /audio/)... "
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$SCHEME://$HOST/audio/")
|
||||
# wzp-web returns 200 for its landing page
|
||||
[ "$STATUS" = "200" ] && echo "OK ($STATUS)" || echo "WARN ($STATUS — wzp-web may not serve GET /)"
|
||||
|
||||
# 6. WebSocket upgrade test
|
||||
echo -n "6. WS upgrade test... "
|
||||
WS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Upgrade: websocket" -H "Connection: Upgrade" "$SCHEME://$HOST/v1/ws/test")
|
||||
echo "($WS_STATUS)"
|
||||
|
||||
# 7. TLS cert check
|
||||
if [ "$SCHEME" = "https" ]; then
|
||||
echo -n "7. TLS cert... "
|
||||
ISSUER=$(echo | openssl s_client -connect "$HOST:443" -servername "$HOST" 2>/dev/null | openssl x509 -noout -issuer 2>/dev/null)
|
||||
echo "$ISSUER" | grep -q "Let's Encrypt\|Cloudflare\|R3\|E1" && echo "OK ($ISSUER)" || echo "$ISSUER"
|
||||
fi
|
||||
|
||||
# 8. IPv6 test
|
||||
echo -n "8. IPv6... "
|
||||
if curl -6 -s -o /dev/null -w "%{http_code}" --connect-timeout 3 "$SCHEME://$HOST/" 2>/dev/null; then
|
||||
echo " (IPv6 reachable)"
|
||||
else
|
||||
echo "not available (IPv4 only)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Done ==="
|
||||
Reference in New Issue
Block a user