Files
easy-asterisk/docker-compose.yml
T
Claude 61b9235f60 Make TURN/STUN port configurable via TURN_PORT env var
UniFi controller uses UDP 3478 for STUN, preventing coturn from
binding. Add TURN_PORT variable (default 3478) so users can set
TURN_PORT=3479 in .env to avoid the conflict.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 01:58:04 +00:00

119 lines
4.2 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:-}
# ── 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
environment:
# Image-native external IP detection (adds --external-ip automatically)
- DETECT_EXTERNAL_IP=${DETECT_EXTERNAL_IP:-yes}
command:
- -n
- --listening-port=${TURN_PORT:-3478}
- --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: