fix(deploy): 修正端口检查、删除死代码、验证走内置nginx
1. 端口检查:80/443 → 11223(内置 nginx 实际使用的端口) 2. 删除 if false 死代码块(旧版 nginx 配置模板,137行无效代码) 3. Step 7 验证:改为 BASE_URL=http://127.0.0.1:11223,不依赖 宿主机或外层 nginx 是否已配置,避免部署后验证误报失败 4. 最终输出:添加多层 nginx 代理场景的 WebSocket 头透传提示 5. verify.sh:移除不存在的 docs-site 容器检查(避免恒定 WARN) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
父节点
2f81f21e42
当前提交
35f07bad95
@ -220,12 +220,12 @@ DISK_FREE_GB="$(df -BG "$ROOT_DIR" | awk 'NR==2{gsub(/G/,"",$4); print $4}')"
|
||||
fail "磁盘可用空间不足(需 ≥10 GB,当前 ${DISK_FREE_GB:-?} GB)"
|
||||
ok "磁盘可用: ${DISK_FREE_GB} GB"
|
||||
|
||||
for port in 80 443; do
|
||||
for port in 11223; do
|
||||
if ss -tlnp 2>/dev/null | grep -q ":${port} " || \
|
||||
netstat -tlnp 2>/dev/null | grep -q ":${port} "; then
|
||||
warn "端口 ${port} 已被占用(继续执行,如已是本脚本容器则无影响)"
|
||||
warn "端口 ${port} 已被占用(如已是本脚本的 nginx 容器则无影响,否则会端口冲突)"
|
||||
else
|
||||
ok "端口 ${port} 空闲"
|
||||
ok "端口 ${port} 空闲(内置 nginx 入口)"
|
||||
fi
|
||||
done
|
||||
|
||||
@ -358,145 +358,6 @@ EOF
|
||||
chmod 600 "$ROOT_DIR/config/tenant/bootstrap.env"
|
||||
ok "config/tenant/bootstrap.env 已写入 (chmod 600)"
|
||||
|
||||
# (nginx 容器默认不启动,用户使用宿主机自己的 nginx 代理到各服务端口)
|
||||
|
||||
if false; then
|
||||
# 以下为内置 nginx 配置示例,仅在 COMPOSE_PROFILES 包含 nginx-bundled 时使用
|
||||
cat > /dev/null << NGINX_CONF
|
||||
# =============================================================================
|
||||
# XuqmGroup 私有化部署 — Nginx HTTPS 配置(由 deploy.sh 自动生成)
|
||||
# 域名: ${DEPLOY_DOMAIN}
|
||||
# =============================================================================
|
||||
|
||||
# HTTP → HTTPS 重定向
|
||||
server {
|
||||
listen 80;
|
||||
server_name ${DEPLOY_DOMAIN};
|
||||
return 301 https://\$host\$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name ${DEPLOY_DOMAIN};
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/${DEPLOY_DOMAIN}/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/${DEPLOY_DOMAIN}/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
|
||||
charset utf-8;
|
||||
client_max_body_size 100m;
|
||||
|
||||
location /health {
|
||||
return 200 "ok\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
location /api/v1/updates/ {
|
||||
proxy_pass http://update-service:8084/api/v1/updates/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location /api/v1/rn/ {
|
||||
proxy_pass http://update-service:8084/api/v1/rn/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 120s;
|
||||
}
|
||||
|
||||
location /api/im/ {
|
||||
proxy_pass http://im-service:8082/api/im/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location /ws/im {
|
||||
proxy_pass http://im-service:8082/ws/im;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_read_timeout 3600s;
|
||||
}
|
||||
|
||||
location /api/license/ {
|
||||
proxy_pass http://license-service:8085/api/license/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location /api/file/ {
|
||||
proxy_pass http://file-service:8086/api/file/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
client_max_body_size 500m;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://tenant-service:9001/api/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location /actuator/ {
|
||||
proxy_pass http://tenant-service:9001/actuator/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
}
|
||||
|
||||
location /file/ {
|
||||
proxy_pass http://file-service:8086/file/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
client_max_body_size 500m;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
|
||||
location /docs/ {
|
||||
proxy_pass http://tenant-web:80/docs/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
}
|
||||
|
||||
location /ops {
|
||||
proxy_pass http://ops-web:80;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://tenant-web:80;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header Accept-Encoding "";
|
||||
sub_filter 'wss://im.dev.xuqinmin.com/ws/im' 'wss://\$host/ws/im';
|
||||
sub_filter 'https://dev.xuqinmin.com' 'https://\$host';
|
||||
sub_filter_once off;
|
||||
sub_filter_types text/javascript application/javascript;
|
||||
}
|
||||
}
|
||||
NGINX_CONF
|
||||
fi
|
||||
|
||||
# config/vendors/push.env — 推送服务厂商凭据(初始为关闭状态,按需开启)
|
||||
mkdir -p "$ROOT_DIR/config/vendors"
|
||||
if [ ! -f "$ROOT_DIR/config/vendors/push.env" ]; then
|
||||
@ -894,14 +755,13 @@ fi
|
||||
# ---------------------------------------------------------------------------
|
||||
step "一键验证所有服务"
|
||||
|
||||
# 将 DEPLOY_HOST 注入到 verify.sh 中使用
|
||||
export DEPLOY_HOST="${DEPLOY_HOST}"
|
||||
|
||||
if bash "$ROOT_DIR/scripts/verify.sh"; then
|
||||
# 验证通过内置 nginx(127.0.0.1:11223)进行,不依赖宿主机或外层 nginx 是否已配置
|
||||
# 内置 nginx 已包含全部路由,所有接口均可通过此端口验证
|
||||
if BASE_URL="http://127.0.0.1:11223" bash "$ROOT_DIR/scripts/verify.sh"; then
|
||||
ok "全量验证通过"
|
||||
else
|
||||
printf '\n\033[33m 部分验证项未通过,请查看上方输出。\033[0m\n'
|
||||
printf ' 可重新运行:DEPLOY_HOST=%s bash %s/scripts/verify.sh\n' "$DEPLOY_HOST" "$ROOT_DIR"
|
||||
printf ' 可重新运行:BASE_URL=http://127.0.0.1:11223 bash %s/scripts/verify.sh\n' "$ROOT_DIR"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -918,7 +778,7 @@ if [ "$DEPLOY_MODE" = "new" ]; then
|
||||
else
|
||||
printf ' 密码: 同生产平台密码(原样迁移,未重置)\n'
|
||||
fi
|
||||
printf '\n \033[1m宿主机 nginx 配置(server 块内加入以下内容即可):\033[0m\n'
|
||||
printf '\n \033[1m192.168.128.88 宿主机 nginx 配置(server 块内加入以下内容):\033[0m\n'
|
||||
printf '\033[0;37m'
|
||||
cat <<'NGINX_REF'
|
||||
location / {
|
||||
@ -934,6 +794,17 @@ cat <<'NGINX_REF'
|
||||
NGINX_REF
|
||||
printf '\033[0m'
|
||||
printf ' 内置 nginx 已处理全部路由,无需再配置各服务端口。\n'
|
||||
printf '\n \033[1;33m注意(多层 nginx 代理):\033[0m\n'
|
||||
printf ' 如上层 nginx 还有多层代理指向 192.168.128.88,\033[1m每一层\033[0m都必须透传 WebSocket 升级头:\n'
|
||||
printf '\033[0;37m'
|
||||
cat <<'WS_NOTE'
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 3600s;
|
||||
WS_NOTE
|
||||
printf '\033[0m'
|
||||
printf ' 缺少这四行,IM WebSocket 握手将在任意一层失败。\n'
|
||||
printf '\n \033[1m部署目录:\033[0m %s\n' "$ROOT_DIR"
|
||||
printf ' \033[1m审计日志:\033[0m %s/logs/audit.log\n' "$ROOT_DIR"
|
||||
printf '\n\033[1;32m 部署成功!在宿主机 nginx 加上以上配置后即可访问:%s\033[0m\n\n' "${CONSOLE_BASE}"
|
||||
printf '\n\033[1;32m 部署成功!在所有 nginx 层配置好后即可访问:%s\033[0m\n\n' "${CONSOLE_BASE}"
|
||||
|
||||
@ -143,7 +143,7 @@ for CTR_SUFFIX in $REQUIRED_CONTAINERS; do
|
||||
fi
|
||||
done
|
||||
|
||||
OPTIONAL_CONTAINERS="file-service im-service push-service update-service license-service docs-site mysql redis"
|
||||
OPTIONAL_CONTAINERS="file-service im-service push-service update-service license-service mysql redis"
|
||||
for CTR_SUFFIX in $OPTIONAL_CONTAINERS; do
|
||||
CTR_NAME=$(docker ps --filter "name=$CTR_SUFFIX" --filter "status=running" --format '{{.Names}}' 2>/dev/null | head -1)
|
||||
if [ -n "$CTR_NAME" ]; then
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户