diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 3f10f6b..adca9e2 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -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}" diff --git a/scripts/verify.sh b/scripts/verify.sh index cf7663b..72e456c 100644 --- a/scripts/verify.sh +++ b/scripts/verify.sh @@ -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