build(docker): Intranet deployment is successfully tested using turn

- Switch all CLI examples to Docker Compose V2 (docker compose) for consistency.
  - Add explicit instruction to grant write permissions to the host logs/ directory (chmod 777 -R logs) to fix coturn/nginx bind-mount logging errors.
  - Parameterize TURN UDP port range via TURN_MIN_PORT/TURN_MAX_PORT and set a safer default 49152-49252 to reduce startup/cleanup overhead and port
  conflicts.
  - Update troubleshooting with coturn log write failure guidance and port conflict hints.
  - Clarify that LAN IP is auto-detected in private mode; --local-ip is no longer needed by default but remains as an override for edge cases.
This commit is contained in:
david_bai
2025-09-30 14:01:30 +08:00
parent 2ee6961634
commit 200fc65617
5 changed files with 197 additions and 35 deletions
+151 -3
View File
@@ -28,6 +28,109 @@ log_error() {
echo -e "${RED}$1${NC}"
}
# 默认与全局参数
WITH_TURN="${WITH_TURN:-false}"
TURN_EXTERNAL_IP_OVERRIDE=""
TURN_MIN_PORT_DEFAULT=49152
TURN_MAX_PORT_DEFAULT=49252
TURN_MIN_PORT="$TURN_MIN_PORT_DEFAULT"
TURN_MAX_PORT="$TURN_MAX_PORT_DEFAULT"
parse_turn_port_range() {
local range="$1"
if [[ -z "$range" ]]; then
return 0
fi
if [[ ! "$range" =~ ^([0-9]{2,5})-([0-9]{2,5})$ ]]; then
log_error "--turn-port-range 格式应为 MIN-MAX,例如 49152-49252"
exit 1
fi
local min="${BASH_REMATCH[1]}"
local max="${BASH_REMATCH[2]}"
if (( min < 1 || max > 65535 || min >= max )); then
log_error "无效端口段:$min-$max,应在 1-65535 且 MIN<MAX"
exit 1
fi
TURN_MIN_PORT="$min"
TURN_MAX_PORT="$max"
}
cleanup_previous_artifacts() {
log_warning "清理上一次生成的配置产物..."
rm -f .env 2>/dev/null || true
rm -f docker/nginx/nginx.conf 2>/dev/null || true
rm -f docker/nginx/conf.d/*.conf 2>/dev/null || true
rm -f docker/coturn/turnserver.conf 2>/dev/null || true
rm -f docker/ssl/* 2>/dev/null || true
}
# 显示帮助信息
show_help() {
cat << 'EOF'
PrivyDrop 配置生成脚本(Docker 版)
用法: bash docker/scripts/generate-config.sh [选项]
选项:
--mode MODE 生成模式: private|basic|public|full
private/basic: 内网HTTP;默认不启用TURN,前端直连后端
public: 公网HTTP + 启用TURN(无域名也可,TURN host=本机IP
full: 完整HTTPS + 启用TURN(建议配合域名)
--with-turn 在任意模式下启用TURN(含private/basic)。默认 external-ip=LOCAL_IP
--turn-external-ip IP 显式指定TURN external-ip;不指定则使用 PUBLIC_IP,否则回退 LOCAL_IP
--turn-port-range R 指定TURN端口段(UDP),格式 MIN-MAX;默认 49152-49252
--domain DOMAIN 指定域名(用于 Nginx/证书/TURN realm,如 turn.DOMAIN
--local-ip IP 指定本机局域网IP(不传则自动探测)
--help 显示本帮助
环境变量(可选):
PUBLIC_IP 显式指定公网IP;仅在 public/full 模式有效。
TURN external-ip 写入优先使用 PUBLIC_IP
留空则回退为 LOCAL_IP(仅同局域网可用,穿透受限)。
生成内容:
- .env 核心环境变量(含 NEXT_PUBLIC_API_URL/CORS 等)
- docker/nginx/* Nginx 反向代理配置(private/basic 也会生成 HTTP 配置)
- docker/ssl/* 自签证书(private/basic/public 生成;full 可替换为正式证书)
- docker/coturn/turnserver.conf 在 public/full 或使用 --with-turn 时生成/覆盖
重要说明:
- TURN external-ip 赋值逻辑为 external-ip=${PUBLIC_IP:-${LOCAL_IP}}
即优先使用 PUBLIC_IP,否则回退 LOCAL_IP。
- private/basic 模式不会覆盖 docker/coturn/turnserver.conf
若此前生成过 TURN 配置,该文件可能保留历史 external-ip。
示例:
# 1) 纯内网(推荐开发/内网快速跑通)
bash docker/scripts/generate-config.sh --mode private [--local-ip 192.168.0.113]
# 2) 内网 + 启用TURN(默认 external-ip=LOCAL_IP,端口段=49152-49252
bash docker/scripts/generate-config.sh --mode private --with-turn [--local-ip 192.168.0.113]
# 3) 内网 + 启用TURN(自定义端口段/显式external-ip
bash docker/scripts/generate-config.sh --mode private --with-turn \
--turn-port-range 56000-56100 --turn-external-ip 192.168.0.113 \
[--local-ip 192.168.0.113]
# 4) 公网HTTP + TURN(自动探测公网IP,不带域名也可)
bash docker/scripts/generate-config.sh --mode public --local-ip 192.168.0.113
# 5) 公网HTTP + TURN(指定公网IP,避免外网探测)
PUBLIC_IP=1.2.3.4 bash docker/scripts/generate-config.sh --mode public --local-ip 192.168.0.113
# 6) HTTPS + TURN(有域名)
bash docker/scripts/generate-config.sh --mode full --domain example.com --local-ip 192.168.0.113
内网带TURN测试提示(不改脚本的最小步骤):
A) 一步生成(推荐):
bash docker/scripts/generate-config.sh --mode private --with-turn --local-ip 192.168.0.113
然后 bash ./deploy.sh --mode private --with-turn
B) 分步生成:
先按 private 生成部署前后端,再 docker compose up -d coturn
EOF
}
# 生成环境变量文件
generate_env_file() {
log_info "生成环境变量配置..."
@@ -77,6 +180,11 @@ generate_env_file() {
turn_enabled="true"
fi
# 若显式启用 TURN,则覆盖模式默认
if [[ "$WITH_TURN" == "true" ]]; then
turn_enabled="true"
fi
if [[ "$turn_enabled" == "true" ]]; then
if [[ -n "$DOMAIN_NAME" ]]; then
turn_host_value="turn.${DOMAIN_NAME}"
@@ -91,6 +199,10 @@ generate_env_file() {
next_public_turn_password="$turn_password"
fi
# 端口段(默认 49152-49252,可被 --turn-port-range 覆盖)
local turn_min_port_value="${TURN_MIN_PORT:-$TURN_MIN_PORT_DEFAULT}"
local turn_max_port_value="${TURN_MAX_PORT:-$TURN_MAX_PORT_DEFAULT}"
local default_no_proxy="localhost,127.0.0.1,backend,frontend,redis,coturn"
local http_proxy_value="${HTTP_PROXY:-${existing_env[HTTP_PROXY]}}"
local https_proxy_value="${HTTPS_PROXY:-${existing_env[HTTPS_PROXY]}}"
@@ -102,6 +214,8 @@ generate_env_file() {
TURN_PASSWORD="$turn_password"
TURN_REALM="$turn_realm_value"
TURN_HOST="$turn_host_value"
TURN_MIN_PORT="$turn_min_port_value"
TURN_MAX_PORT="$turn_max_port_value"
cat > "$env_file" << EOF
# PrivyDrop Docker 配置文件
@@ -153,6 +267,8 @@ TURN_ENABLED=${turn_enabled}
TURN_USERNAME=${turn_username_value}
TURN_PASSWORD=${turn_password}
TURN_REALM=${turn_realm_value}
TURN_MIN_PORT=${turn_min_port_value}
TURN_MAX_PORT=${turn_max_port_value}
# =============================================================================
# Nginx配置
@@ -495,6 +611,19 @@ generate_coturn_config() {
mkdir -p docker/coturn
# 计算 external-ip:优先 --turn-external-ip,再次 PUBLIC_IP,最后 LOCAL_IP
local external_ip_value
if [[ -n "$TURN_EXTERNAL_IP_OVERRIDE" ]]; then
external_ip_value="$TURN_EXTERNAL_IP_OVERRIDE"
elif [[ -n "$PUBLIC_IP" ]]; then
external_ip_value="$PUBLIC_IP"
else
external_ip_value="$LOCAL_IP"
fi
local min_port_value="${TURN_MIN_PORT:-$TURN_MIN_PORT_DEFAULT}"
local max_port_value="${TURN_MAX_PORT:-$TURN_MAX_PORT_DEFAULT}"
cat > docker/coturn/turnserver.conf << EOF
# PrivyDrop TURN服务器配置
# 自动生成时间: $(date)
@@ -508,7 +637,7 @@ listening-ip=0.0.0.0
relay-ip=0.0.0.0
# 外部IP (用于NAT环境)
external-ip=${PUBLIC_IP:-${LOCAL_IP}}
external-ip=${external_ip_value}
# 服务器域名
realm=${TURN_REALM}
@@ -535,8 +664,8 @@ no-loopback-peers
no-multicast-peers
# 性能配置
min-port=49152
max-port=65535
min-port=${min_port_value}
max-port=${max_port_value}
# 数据库 (可选)
# userdb=/var/lib/turn/turndb
@@ -634,12 +763,31 @@ main() {
LOCAL_IP_OVERRIDE="$2"
shift 2
;;
--with-turn)
WITH_TURN="true"
shift
;;
--turn-external-ip)
TURN_EXTERNAL_IP_OVERRIDE="$2"
shift 2
;;
--turn-port-range)
parse_turn_port_range "$2"
shift 2
;;
--help)
show_help
exit 0
;;
*)
shift
;;
esac
done
# 先清理上一次生成物(避免历史残留误导)
cleanup_previous_artifacts
# 首先运行环境检测
if ! detect_network_environment; then
log_error "环境检测失败"