Skip to content
bitzorcas
中EN

Guide

1Panel OpenResty 单机蓝绿

在 1Panel OpenResty 反代站点上用 named upstream 做单机蓝绿切流,避免把 upstream 写进 server 上下文或写死 8082 端口。

Last updated

单机预览或小型生产可以用蓝绿两套 systemd 单元,用 OpenResty 的 named upstream 切 Gateway 端口。前端仍走 deploy-frontend.sh 的 current 软链接。环境变量、种子和 CORS 见 1Panel 开发预览;本页只解决「面板反代配不上、切流 502」和发布命令。

为什么 1Panel 反代站点会失败

官方 OpenResty 应用(1Panel app store 1.31.x)的实际布局:

宿主机 ${WEBSITE_DIR}/conf.d/*.conf
→ 容器 /usr/local/openresty/nginx/conf/conf.d/*.conf
→ nginx.conf 在 http {} 里 include
宿主机 ${WEBSITE_DIR}/sites/<别名>/proxy/*.conf
→ 被站点 server {} include(只能放 location / proxy_pass)
错误做法结果
写 /opt/1panel/apps/openresty/openresty/conf/upstreams/*.conf官方镜像不 include 该目录,改端口不会切流
docker exec 1panel-openresty nginx -s reload容器名几乎一定是 1Panel-openresty-<id>,reload 失败
把 upstream {} 贴进自定义配置upstream directive is not allowed here
反向代理填 http://127.0.0.1:8082永远打蓝区;脚本停蓝区后对外 502
OpenResty 为 bridge 且 Kestrel 绑 127.0.0.1容器 loopback 不是宿主机,502

正确拓扑:

浏览器 → OpenResty location
proxy_pass http://bitzorcas_gateway_preview;
↑
${WEBSITE_DIR}/conf.d/00-bitzorcas-preview-upstream.conf
(http 上下文,脚本只改 server 端口)
↓
127.0.0.1:8082 蓝 Gateway 或 127.0.0.1:9082 绿 Gateway
↓
同色 API 8080/9080 同色 JobHost 8081/9081

端口与目录

颜色APIJobHostGateway目录
蓝808080818082/www/apps/<env>-blue
绿908090819082/www/apps/<env>-green
当前———/www/apps/<env> 软链接

systemd 名:bitzorcas-{api,jobhost,gateway}-<env>-{blue,green}。

原先用 deploy.sh 生成的 /www/apps/<env> 真实目录,第一次蓝绿会改名为 <env>-blue 并补软链接。程序若放在 /srv/sites/bitzorcas,部署时设置 BITZORCAS_APP_ROOT。

切流窗口内两个 JobHost 会短暂同时运行。连接串可用时 Quartz 使用 AdoJobStore + clustering,同一 Job 只会被一个实例执行。绿区 Gateway 的下游地址由 systemd Environment= 覆盖成 9080,避免 env 文件里写死的 8080 把绿区指回蓝区 API。

一次性接线

把脚本和 lib/common.sh 一起装到 /www/scripts/(缺 lib 会直接失败):

Terminal window
# ① 开发机:脚本和 lib 必须一起上传,否则服务器 source 会失败。
scp scripts/deploy/deploy-blue-green.sh scripts/deploy/deploy-rollback.sh \
scripts/deploy/setup-1panel-openresty.sh deploy@server:/tmp/
scp -r scripts/deploy/lib deploy@server:/tmp/deploy-lib
# ② 服务器:先安装三件套和 common.sh,再写 http 级 upstream。
sudo install -m 0755 /tmp/setup-1panel-openresty.sh /www/scripts/
sudo install -m 0755 /tmp/deploy-blue-green.sh /www/scripts/
sudo install -m 0755 /tmp/deploy-rollback.sh /www/scripts/
sudo mkdir -p /www/scripts/lib
sudo install -m 0644 /tmp/deploy-lib/common.sh /www/scripts/lib/common.sh
# ③ 只接线,不启停 systemd。location 未改 named upstream 时会失败并打印步骤。
sudo /www/scripts/setup-1panel-openresty.sh preview

脚本探测容器、${WEBSITE_DIR} 和网络模式,写入 http 级 upstream,然后 nginx -t 并 reload。若 location 仍写死 127.0.0.1:8082,它会失败并打印面板步骤——这是验收,不是脚本损坏。

完整可复制配置

日常仍应跑 setup-1panel-openresty.sh:它写入的就是下面这段,并负责探测路径与 reload。没有脚本时可以手写,但 upstream {} 只能写到 http 级文件,不能贴进网站「自定义配置」。

http 级 upstream

write_openresty_upstream(scripts/deploy/lib/common.sh)在 preview / 蓝区写入的完整文件:

条件宿主机落点
默认${WEBSITE_DIR}/conf.d/00-bitzorcas-preview-upstream.conf
已设站点别名且存在 sites/<别名>/upstream/${WEBSITE_DIR}/sites/<别名>/upstream/bitzorcas_gateway_preview.conf

${WEBSITE_DIR} 是 OpenResty 容器 /www 的宿主机源,1Panel 常见为 /opt/1panel/www。不要写到 /opt/1panel/apps/openresty/openresty/conf/upstreams/。

00-bitzorcas-preview-upstream.conf
# Managed by BitzOrcas blue-green. This file must stay in http context.
# Do not paste the upstream block into a 1Panel website server / 自定义配置.
upstream bitzorcas_gateway_preview {
server 127.0.0.1:8082;
keepalive 32;
}

蓝绿脚本切到绿区时只改端口,名称不变:

绿区只改 server 端口
upstream bitzorcas_gateway_preview {
server 127.0.0.1:9082;
keepalive 32;
}

环境名不是 preview 时:文件名改成 00-bitzorcas-<env>-upstream.conf,块名改成 bitzorcas_gateway_<env>,并与下面 location 的 proxy_pass 一致。

若 upstream 写在 sites/<别名>/upstream/,站点主文件 ${WEBSITE_DIR}/conf.d/<别名>.conf 顶部必须有一行 http 级 include /www/sites/<别名>/upstream/*.conf;(容器内路径)。setup 脚本会自动补。不要把这行 include 写进 server {}。

没有 setup 脚本时,把蓝区内容写到默认落点:

Terminal window
# 手写 preview 蓝区 upstream。文件必须落在 http 上下文的 conf.d,不要贴进网站自定义配置。
# 先 inspect 确认 /www 的宿主机源,再改 WEBSITE_DIR;1Panel 常见是 /opt/1panel/www。
OPENRESTY="$(sudo docker ps --format '{{.Names}}' | grep -Ei openresty | head -n1)"
sudo docker inspect "$OPENRESTY" --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}'
WEBSITE_DIR=/opt/1panel/www
sudo mkdir -p "${WEBSITE_DIR}/conf.d"
sudo tee "${WEBSITE_DIR}/conf.d/00-bitzorcas-preview-upstream.conf" >/dev/null <<'EOF'
# Managed by BitzOrcas blue-green. This file must stay in http context.
# Do not paste the upstream block into a 1Panel website server / 自定义配置.
upstream bitzorcas_gateway_preview {
server 127.0.0.1:8082;
keepalive 32;
}
EOF
sudo docker exec "$OPENRESTY" nginx -t
sudo docker exec "$OPENRESTY" nginx -s reload

日常切流不要手改端口,交给 deploy-blue-green.sh / deploy-rollback.sh。

include 链

官方镜像的 nginx.conf 在 http 里已经 include conf.d。不要手改 OpenResty 应用目录里的主配置去加 upstreams/,面板升级或重建容器会丢掉。

nginx.conf 的 http 片段(官方镜像已有,不要手改)
http {
# conf.d 挂的是宿主机 ${WEBSITE_DIR}/conf.d,不是应用目录下的 conf/upstreams/。
include /usr/local/openresty/nginx/conf/conf.d/*.conf;
}

因此宿主机 conf.d 里的每个 *.conf 都处于 http 上下文:既可以放 upstream {},也可以放整个 server {}。1Panel 站点主文件也在这里。

宿主机 ${WEBSITE_DIR}/conf.d/*.conf
→ 容器 /usr/local/openresty/nginx/conf/conf.d/*.conf
→ 被 nginx.conf 在 http {} 里 include
├─ 00-bitzorcas-preview-upstream.conf http:只放 upstream {}
└─ <站点别名>.conf http:顶部可 include upstream,然后是 server {}
宿主机 ${WEBSITE_DIR}/sites/<别名>/upstream/*.conf
→ 容器 /www/sites/<别名>/upstream/*.conf
→ 必须由站点主文件在 server {} 之前 include(http)
→ setup 脚本在设了 BITZORCAS_OPENRESTY_SITE 且该目录存在时走这条
宿主机 ${WEBSITE_DIR}/sites/<别名>/proxy/*.conf
→ 容器 /www/sites/<别名>/proxy/*.conf
→ 只能从 server {} 里 include(location / proxy_pass)

推荐默认用 conf.d/00-bitzorcas-preview-upstream.conf,站点主文件不必再 include 一次。只有 upstream 写在 sites/<别名>/upstream/ 时,才在站点主文件顶部加一行。下面是 1Panel 风格的完整 include 示例(证书、rewrite、waf 等行以面板现有文件为准,不要删面板生成的 include):

<站点别名>.conf(include 写法)
# 宿主机: ${WEBSITE_DIR}/conf.d/app.example.com.conf
# 本文件被 nginx.conf 在 http {} 里加载。upstream 的 include 必须在 server {} 之前。
# 默认已写 conf.d/00-bitzorcas-preview-upstream.conf 时,不要重复这一行。
include /www/sites/app.example.com/upstream/*.conf;
server {
listen 80;
listen 443 ssl http2;
server_name app.example.com;
# 证书路径以 1Panel「配置文件」里现有 ssl 为准。
ssl_certificate /www/sites/app.example.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/app.example.com/ssl/privkey.pem;
root /www/sites/bitzorcas-preview/current;
index index.html;
access_log /www/sites/app.example.com/log/access.log;
error_log /www/sites/app.example.com/log/error.log;
# 以下都在 server {} 内,只能放 location / 头 / 证书补充,不能放 upstream {}。
include /www/sites/app.example.com/proxy/*.conf;
include /www/sites/app.example.com/rewrite/*.conf;
include /www/sites/app.example.com/ssl/*.conf;
include /www/sites/app.example.com/redirect/*.conf;
include /www/sites/app.example.com/auth/*.conf;
include /www/sites/app.example.com/error_page/*.conf;
include /www/sites/app.example.com/waf/*.conf;
}

用面板「反向代理」时,每个路径会生成 sites/<别名>/proxy/*.conf。把代理地址改成 http://bitzorcas_gateway_preview 后,那些文件里应是 proxy_pass http://bitzorcas_gateway_preview;,不要再写 127.0.0.1:8082。不用面板反代时,把下一节完整 server {} 写进站点主文件,或把再下一节 location 贴进「自定义配置」。

完整 server(站点主文件)

下面两份是可直接覆盖/对照的站点主文件。upstream {} 不在这里;它已经在 00-bitzorcas-preview-upstream.conf。把 root、server_name、证书路径改成容器内真实值。不要 listen 8081(JobHost)。

域名 + HTTPS:

app.example.com.conf
# 宿主机: ${WEBSITE_DIR}/conf.d/app.example.com.conf
# 本文件处于 http 上下文,但只写 server {}。不要在这里声明 upstream {}。
server {
listen 80;
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /www/sites/app.example.com/ssl/fullchain.pem;
ssl_certificate_key /www/sites/app.example.com/ssl/privkey.pem;
root /www/sites/bitzorcas-preview/current;
index index.html;
access_log /www/sites/app.example.com/log/access.log;
error_log /www/sites/app.example.com/log/error.log;
if ($scheme = http) {
return 301 https://$host$request_uri;
}
location ^~ /.well-known/acme-challenge {
allow all;
root /usr/share/nginx/html;
}
location /api/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /hubs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 3600s;
proxy_buffering off;
}
location /health/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /openapi/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /scalar/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /docs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location / {
try_files $uri $uri/ /index.html =404;
}
}

仅 IP(家宽常见入口 8088):

<公网IP>.conf
# 宿主机: ${WEBSITE_DIR}/conf.d/<公网IP>.conf
# 公网 80 常被光猫占用时 listen 8088。不要 listen 8081。
# CORS / Frontend__BaseUrl 必须带端口,例如 http://10.10.10.10:8088。
server {
listen 8088;
server_name <公网IP>;
root /www/sites/bitzorcas-preview/current;
index index.html;
access_log /www/sites/bitzorcas-preview/log/access.log;
error_log /www/sites/bitzorcas-preview/log/error.log;
location /api/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /hubs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 3600s;
proxy_buffering off;
}
location /health/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /openapi/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /scalar/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /docs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location / {
try_files $uri $uri/ /index.html =404;
}
}

server 级 location

只改 1Panel「自定义配置」、不整份覆盖站点主文件时,贴下面这一段。对应仓库 deploy/1panel/openresty-app.locations-blue-green.conf。先保证 http 级 upstream 已存在。把 root 改成容器内能看到的前端 current。

openresty-app.locations-blue-green.conf
# 粘贴到 1Panel 网站的「自定义配置」或配置文件的 server {} 内。
# 必须先写出 http 级 upstream。环境名不是 preview 时改 bitzorcas_gateway_<env>。
root /www/sites/bitzorcas-preview/current;
index index.html;
location /api/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /hubs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_read_timeout 3600s;
proxy_buffering off;
}
location /health/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /openapi/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /scalar/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location /docs/ {
proxy_pass http://bitzorcas_gateway_preview;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
location / {
try_files $uri $uri/ /index.html =404;
}

面板步骤

  1. 网站类型用 静态网站。静态 root 指向前端 current(容器内路径)。
  2. 不要把站点类型做成「反向代理」后再填死 8082。
  3. 任选其一:
    • 反向代理的代理地址改为 http://bitzorcas_gateway_preview(不要 IP、不要端口);
    • 或把「完整 server」贴进站点主文件,或把 location 段贴进自定义配置。不要把 upstream {} 一起贴进去。
  4. /api/、/hubs/、/health/、/openapi/、/scalar/、/docs/ 全部走 named upstream。
  5. 转发头用 $http_host 和 X-Forwarded-Port $server_port。只用 $host 会在 8088 这类入口丢掉端口,登录 Origin 校验 403。
  6. OpenResty 必须是 host 网络。docker inspect <容器> --format '{{.HostConfig.NetworkMode}}' 不是 host 时,先在应用编辑里改网络并重建。

再跑一次 setup,直到输出「OpenResty 已接线」。

发布与回滚

Terminal window
# ① 开发机打包与单色发布相同;增量包仍要先拉服务器 manifest。
VERSION="$(date +%Y%m%d-%H%M)"
./scripts/deploy/pack.sh preview "$VERSION"
scp ../publish/<分支>/bitzorcas-preview-${VERSION}.zip deploy@server:/www/releases/
# ② 服务器:在空闲颜色安装,健康检查通过后再改 upstream。
sudo BITZORCAS_DEPLOY_DB_MODE=schema-only \
/www/scripts/deploy-blue-green.sh \
/www/releases/bitzorcas-preview-${VERSION}.zip \
preview
# ③ 确认当前颜色与 OpenResty 接线;紧急回切不回滚数据库。
sudo /www/scripts/deploy-blue-green.sh --status preview
sudo /www/scripts/deploy-rollback.sh preview

健康检查失败或 OpenResty 未接线时不会改 upstream。只保留一代旧颜色;连续发两次后更早的目录会被覆盖。破坏性 schema 不能靠切颜色撤销。

可选:BITZORCAS_PUBLIC_HEALTH_URL=https://app.example.com/health/ready 在 reload 后再探一次公开入口。

验收

Terminal window
# ① 先看当前颜色,再打本机 Gateway 与公开入口。
sudo /www/scripts/deploy-blue-green.sh --status preview
curl -fsS http://127.0.0.1:8082/health/ready
curl -fsS <PUBLIC_BASE>/health/ready
# ② nginx -T 必须同时出现 upstream 定义和 named proxy_pass。
sudo docker exec "$(sudo docker ps --format '{{.Names}}' | grep -Ei openresty)" nginx -T \
| grep -E 'upstream bitzorcas_gateway_|proxy_pass http://bitzorcas_gateway_'

nginx -T 必须同时出现 upstream 定义和 proxy_pass http://bitzorcas_gateway_<env>。

故障

现象处理
upstream directive is not allowed here从网站自定义配置删除 upstream {},改用 setup 脚本写 conf.d/00-*.conf
setup 说 location 未使用 named upstream反代仍指向 127.0.0.1:8082
找不到容器 1panel-openrestydocker ps | grep -i openresty,或设 BITZORCAS_OPENRESTY_CONTAINER
切绿区后 502未接线就切流;先 rollback,再补 location
绿区 Gateway 仍访问 8080使用当前 deploy-blue-green.sh(unit 用 Environment= 覆盖端口)
bridge 网络 502OpenResty 改为 host 网络
前端 rewrite cycle /index.html容器看不到 current,按预览手册挂载站点目录

另见

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%