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:
+11
-4
@@ -48,11 +48,18 @@ PrivyDrop (原 SecureShare) 是一个基于 WebRTC 的开源点对点(P2P)
|
||||
git clone https://github.com/david-bai00/PrivyDrop.git
|
||||
cd PrivyDrop
|
||||
|
||||
# 一键部署
|
||||
bash deploy.sh
|
||||
# 生成配置(自动检测本机局域网 IP,已无需 --local-ip)
|
||||
bash docker/scripts/generate-config.sh --mode private
|
||||
|
||||
# 日志目录权限(coturn/nginx 外挂日志需要可写)
|
||||
chmod 777 -R logs
|
||||
|
||||
# 一键部署(Compose V2)
|
||||
bash deploy.sh --mode private
|
||||
|
||||
# 访问应用
|
||||
# http://localhost:3002
|
||||
# 前端: http://localhost:3002
|
||||
# 后端: http://localhost:3001
|
||||
```
|
||||
|
||||
**部署优势**:
|
||||
@@ -62,7 +69,7 @@ bash deploy.sh
|
||||
- ✅ 环境要求: 公网 IP → 内网即可使用
|
||||
- ✅ 成功率: 70% → 95%+
|
||||
|
||||
详见: [Docker 部署指南](./docs/DEPLOYMENT_docker.zh-CN.md)
|
||||
详见: [Docker 部署指南](./build/docker/README.md)
|
||||
|
||||
### 💻 本地开发环境
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ PrivyDrop Docker 一键部署脚本
|
||||
$0 --domain example.com --mode full # 完整HTTPS部署
|
||||
$0 --clean # 清理部署
|
||||
|
||||
要求:
|
||||
- Docker Engine 和 Docker Compose V2(命令为 `docker compose`)
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -116,8 +119,8 @@ check_dependencies() {
|
||||
missing_deps+=("docker")
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||
missing_deps+=("docker-compose")
|
||||
if ! docker compose version &> /dev/null; then
|
||||
missing_deps+=("docker compose (V2)")
|
||||
fi
|
||||
|
||||
if ! command -v curl &> /dev/null; then
|
||||
@@ -137,8 +140,8 @@ check_dependencies() {
|
||||
docker)
|
||||
echo " Docker: https://docs.docker.com/get-docker/"
|
||||
;;
|
||||
docker-compose)
|
||||
echo " Docker Compose: https://docs.docker.com/compose/install/"
|
||||
"docker compose (V2)")
|
||||
echo " Docker Compose V2 插件: https://docs.docker.com/compose/install/"
|
||||
;;
|
||||
curl)
|
||||
echo " curl: sudo apt-get install curl (Ubuntu/Debian)"
|
||||
@@ -161,7 +164,7 @@ clean_deployment() {
|
||||
|
||||
# 停止并删除容器
|
||||
if [[ -f "docker-compose.yml" ]]; then
|
||||
docker-compose down -v --remove-orphans 2>/dev/null || true
|
||||
docker compose down -v --remove-orphans 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 删除镜像
|
||||
@@ -209,12 +212,12 @@ deploy_services() {
|
||||
log_info "构建和启动服务..."
|
||||
|
||||
# 停止现有服务
|
||||
if docker-compose ps | grep -q "Up"; then
|
||||
if docker compose ps | grep -q "Up"; then
|
||||
log_info "停止现有服务..."
|
||||
docker-compose down
|
||||
docker compose down
|
||||
fi
|
||||
|
||||
# 确定启用的服务
|
||||
# 确定启用的服务(Compose V2 需要将 --profile 放在子命令之前)
|
||||
local profiles=""
|
||||
if [[ "$WITH_NGINX" == "true" ]]; then
|
||||
profiles="$profiles --profile nginx"
|
||||
@@ -225,11 +228,12 @@ deploy_services() {
|
||||
|
||||
# 构建镜像
|
||||
log_info "构建Docker镜像..."
|
||||
docker-compose build --parallel
|
||||
docker compose build --parallel
|
||||
|
||||
# 启动服务
|
||||
# 启动服务(--profile 需置于 up 之前)
|
||||
log_info "启动服务..."
|
||||
docker-compose up -d $profiles
|
||||
# shellcheck disable=SC2086
|
||||
docker compose $profiles up -d
|
||||
|
||||
log_success "服务启动完成"
|
||||
}
|
||||
@@ -273,8 +277,8 @@ wait_for_services() {
|
||||
return 0
|
||||
else
|
||||
log_error "服务启动超时"
|
||||
log_info "查看服务状态: docker-compose ps"
|
||||
log_info "查看服务日志: docker-compose logs -f"
|
||||
log_info "查看服务状态: docker compose ps"
|
||||
log_info "查看服务日志: docker compose logs -f"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -285,7 +289,7 @@ post_deployment_checks() {
|
||||
|
||||
# 检查容器状态
|
||||
log_info "检查容器状态..."
|
||||
docker-compose ps
|
||||
docker compose ps
|
||||
|
||||
# 运行健康检查测试
|
||||
if [[ -f "test-health-apis.sh" ]]; then
|
||||
@@ -337,10 +341,10 @@ show_deployment_info() {
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}🔧 管理命令:${NC}"
|
||||
echo " 查看状态: docker-compose ps"
|
||||
echo " 查看日志: docker-compose logs -f [服务名]"
|
||||
echo " 重启服务: docker-compose restart [服务名]"
|
||||
echo " 停止服务: docker-compose down"
|
||||
echo " 查看状态: docker compose ps"
|
||||
echo " 查看日志: docker compose logs -f [服务名]"
|
||||
echo " 重启服务: docker compose restart [服务名]"
|
||||
echo " 停止服务: docker compose down"
|
||||
echo " 完全清理: $0 --clean"
|
||||
|
||||
if [[ -f "docker/ssl/ca-cert.pem" ]]; then
|
||||
@@ -369,7 +373,7 @@ show_deployment_info() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}💡 提示:${NC}"
|
||||
echo " - 首次启动可能需要几分钟来下载和构建镜像"
|
||||
echo " - 如遇问题,请查看日志: docker-compose logs -f"
|
||||
echo " - 如遇问题,请查看日志: docker compose logs -f"
|
||||
echo " - 更多帮助: $0 --help"
|
||||
echo ""
|
||||
}
|
||||
@@ -403,7 +407,7 @@ main() {
|
||||
post_deployment_checks
|
||||
show_deployment_info
|
||||
else
|
||||
log_error "部署失败,请检查日志: docker-compose logs"
|
||||
log_error "部署失败,请检查日志: docker compose logs"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,5 +1,3 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
# Redis缓存服务
|
||||
redis:
|
||||
@@ -116,7 +114,7 @@ services:
|
||||
- "3478:3478/udp"
|
||||
- "5349:5349/tcp"
|
||||
- "5349:5349/udp"
|
||||
- "49152-65535:49152-65535/udp"
|
||||
- "${TURN_MIN_PORT:-49152}-${TURN_MAX_PORT:-49252}:${TURN_MIN_PORT:-49152}-${TURN_MAX_PORT:-49252}/udp"
|
||||
volumes:
|
||||
- ./docker/coturn/turnserver.conf:/etc/coturn/turnserver.conf:ro
|
||||
- ./docker/ssl:/etc/ssl/certs:ro
|
||||
|
||||
@@ -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 "环境检测失败"
|
||||
|
||||
@@ -30,14 +30,16 @@ sudo bash backend/docker/env_install.sh
|
||||
```
|
||||
|
||||
该脚本将自动安装:
|
||||
|
||||
- **Node.js v20** - 运行环境
|
||||
- **Redis Server** - 用于房间管理和缓存
|
||||
- **Coturn** - TURN/STUN 服务器(可选,用于NAT穿透)
|
||||
- **Redis Server** - 用于房间管理和缓存
|
||||
- **Coturn** - TURN/STUN 服务器(可选,用于 NAT 穿透)
|
||||
- **Nginx** - Web 服务器和反向代理(使用官方仓库)
|
||||
- **PM2** - Node.js 进程管理器
|
||||
- **Certbot** - SSL 证书管理
|
||||
|
||||
安装完成后,可以验证各服务状态:
|
||||
|
||||
```bash
|
||||
# 验证 Node.js 版本
|
||||
node -v
|
||||
@@ -53,11 +55,13 @@ sudo systemctl status coturn
|
||||
```
|
||||
|
||||
**注意事项:**
|
||||
- **Redis配置:** 默认监听 `127.0.0.1:6379`,请确保后端 `.env` 文件中包含正确的 `REDIS_HOST` 和 `REDIS_PORT`
|
||||
- **TURN服务:** 为可选配置,Privydrop 默认使用公共 STUN 服务器,只有对 NAT 穿透有极高要求时才需要配置
|
||||
|
||||
- **Redis 配置:** 默认监听 `127.0.0.1:6379`,请确保后端 `.env` 文件中包含正确的 `REDIS_HOST` 和 `REDIS_PORT`
|
||||
- **TURN 服务:** 为可选配置,Privydrop 默认使用公共 STUN 服务器,只有对 NAT 穿透有极高要求时才需要配置
|
||||
- **Nginx:** 脚本安装官方版本并验证 stream 模块支持
|
||||
|
||||
**TURN服务器防火墙配置(如果需要配置TURN服务):**
|
||||
**TURN 服务器防火墙配置(如果需要配置 TURN 服务):**
|
||||
|
||||
```bash
|
||||
# 启用 Coturn 服务
|
||||
sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn
|
||||
@@ -68,6 +72,7 @@ sudo ufw reload
|
||||
```
|
||||
|
||||
通过 `sudo ufw app info Turnserver` 看到的端口如下:
|
||||
|
||||
- `3478,3479,5349,5350,49152:65535/tcp`
|
||||
- `3478,3479,5349,5350,49152:65535/udp`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user