Replace the coturn image's fragile eval-based entrypoint with a robust wrapper that handles external IP detection without word-splitting issues. The image's `exec $(eval "echo $@")` produces empty tokens when DETECT_EXTERNAL_IP's DNS lookup fails → "ERROR: CONFIG: Unknown argument:" Also add --listening-ip=0.0.0.0 so coturn binds a single wildcard address instead of enumerating every host interface (reduces log noise). https://claude.ai/code/session_01KWVtEt9MmZdywcu7WmgchX
126 lines
4.5 KiB
YAML
126 lines
4.5 KiB
YAML
# ================================================================
|
|
# Easy Asterisk - Docker Compose
|
|
#
|
|
# Usage:
|
|
# docker compose up -d # Start everything
|
|
# docker exec -it easy-asterisk easy-asterisk # Interactive management
|
|
# docker exec -it easy-asterisk vpn-diagnostics # VPN diagnostics
|
|
#
|
|
# All clients connect via FQDN (TLS) regardless of their network.
|
|
# coturn provides STUN (NAT detection) + TURN (media relay) so calls
|
|
# work even behind strict firewalls, cellular NAT, or VPNs like Proton.
|
|
# ================================================================
|
|
|
|
services:
|
|
|
|
# ── Asterisk PBX ───────────────────────────────────────────
|
|
asterisk:
|
|
build: .
|
|
container_name: easy-asterisk
|
|
# Host networking required for:
|
|
# - RTP media ports (10000-20000 UDP) - too many to map individually
|
|
# - Proper NAT detection and SIP Contact headers
|
|
# - Direct access to coturn on localhost
|
|
network_mode: host
|
|
depends_on:
|
|
coturn:
|
|
condition: service_healthy
|
|
volumes:
|
|
- asterisk-config:/etc/asterisk
|
|
- easy-asterisk-config:/etc/easy-asterisk
|
|
- asterisk-logs:/var/log/asterisk
|
|
- asterisk-spool:/var/spool/asterisk
|
|
- asterisk-lib:/var/lib/asterisk
|
|
environment:
|
|
# ── Domain (REQUIRED for remote access) ──
|
|
# Your FQDN that points to this server's public IP
|
|
- DOMAIN_NAME=${DOMAIN_NAME:?Set DOMAIN_NAME in .env}
|
|
- ENABLE_TLS=${ENABLE_TLS:-y}
|
|
|
|
# ── Public IP ──
|
|
# Auto-detected if empty. Set manually if detection fails.
|
|
- PUBLIC_IP=${PUBLIC_IP:-}
|
|
|
|
# ── Local Network ──
|
|
- LOCAL_CIDR=${LOCAL_CIDR:-}
|
|
|
|
# ── Additional Subnets ──
|
|
# Space-separated CIDRs for VLANs, site-to-site VPNs, etc.
|
|
# NOT needed for client-side VPNs (Proton, NordVPN) - TURN handles those
|
|
- HAS_VLANS=${HAS_VLANS:-n}
|
|
- VLAN_SUBNETS=${VLAN_SUBNETS:-}
|
|
|
|
# ── TURN/STUN Server ──
|
|
# Points to the coturn service (auto-configured)
|
|
- TURN_ENABLED=y
|
|
- TURN_SERVER=${DOMAIN_NAME:?}:${TURN_PORT:-3478}
|
|
- TURN_USERNAME=${TURN_USERNAME:-easyasterisk}
|
|
- TURN_PASSWORD=${TURN_PASSWORD:-changeme}
|
|
|
|
# ── RTP Port Range ──
|
|
- RTP_START=${RTP_START:-10000}
|
|
- RTP_END=${RTP_END:-20000}
|
|
|
|
# ── Web Admin ──
|
|
- WEB_ADMIN_PORT=${WEB_ADMIN_PORT:-8080}
|
|
- WEB_ADMIN_AUTH_DISABLED=${WEB_ADMIN_AUTH_DISABLED:-false}
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "asterisk", "-rx", "core show version"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
|
|
# ── TURN/STUN Relay Server (coturn) ──────────────────────────
|
|
# Provides:
|
|
# STUN - Tells clients their public IP (NAT detection)
|
|
# TURN - Relays media when direct UDP paths are blocked
|
|
# (corporate firewalls, cellular NAT, Proton VPN, etc.)
|
|
#
|
|
# Without TURN, calls work "sometimes" - with TURN, they always work.
|
|
coturn:
|
|
image: coturn/coturn:latest
|
|
container_name: easy-asterisk-coturn
|
|
network_mode: host
|
|
# The coturn image runs as nobody:nogroup by default, which cannot
|
|
# create /var/run/turnserver.pid. Run as root to avoid this.
|
|
user: root
|
|
# Custom entrypoint bypasses the coturn image's fragile eval-based
|
|
# entrypoint which causes "Unknown argument:" errors when IP detection
|
|
# returns empty. Our wrapper handles detection robustly.
|
|
entrypoint: ["/coturn-entrypoint.sh"]
|
|
volumes:
|
|
- ./docker/coturn-entrypoint.sh:/coturn-entrypoint.sh:ro
|
|
environment:
|
|
# Passed to our entrypoint for --external-ip. Auto-detected if empty.
|
|
- PUBLIC_IP=${PUBLIC_IP:-}
|
|
command:
|
|
- -n
|
|
- --listening-port=${TURN_PORT:-3478}
|
|
- --listening-ip=0.0.0.0
|
|
- --fingerprint
|
|
- --lt-cred-mech
|
|
- --user=${TURN_USERNAME:-easyasterisk}:${TURN_PASSWORD:-changeme}
|
|
- --realm=${DOMAIN_NAME:-localhost}
|
|
- --min-port=${TURN_RELAY_MIN:-49152}
|
|
- --max-port=${TURN_RELAY_MAX:-49252}
|
|
- --no-tls
|
|
- --no-dtls
|
|
- --no-cli
|
|
- --no-multicast-peers
|
|
- --log-file=stdout
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "turnutils_stunclient -p ${TURN_PORT:-3478} 127.0.0.1 >/dev/null 2>&1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|
|
|
|
volumes:
|
|
asterisk-config:
|
|
easy-asterisk-config:
|
|
asterisk-logs:
|
|
asterisk-spool:
|
|
asterisk-lib:
|