跳到主要内容

域名与反向代理

使用域名(特别是 HTTPS)而非 IP 地址来服务工作室时的配置。 本章必须按顺序全部完成才能生效。 即使漏掉一项,也会出现看似不同的症状,如“预览空白”、“构建聊天连接错误”、“部署应用数据返回 401”等。


域名只有一个​

预览和部署应用都在与工作室相同域名的 /container/ 下提供服务。

https://studio.company.com/ → 스튜디오 UI + API
https://studio.company.com/container/… → 프리뷰 · 배포앱

所需的是 1 条 DNS 记录、1 张证书、1 个 vhost。

应用也使用相同域名

我们不将应用分离到独立主机。由于预览和部署地址都是相对路径,在仅开放 80/443 的反向代理配置中可以直接工作。

代价——我们放弃了源站隔离

预览和部署应用是由聊天生成的代码,即不可信内容。它们在与工作室相同的源站上运行——这意味着放弃了通过分离源站获得的隔离。这是为了将域名缩减为一个而接受的权衡。

因此,请不要将应用创建权限授予不可信用户。 此配置的前提是仅将构建者角色授予内部运维人员。


准备事项清单​

  • DNS A 记录 1 条
  • 该主机名的 TLS 证书
  • 反向代理能访问工作室盒子的 :80
  • 在工作室盒子防火墙上允许 代理 → :80
:5171 无需开放

应用监听器 (:5171) 由工作室盒子内的 web nginx 将 /container/ · /apps/ · /preview/ 转发过去,因此无需对外暴露。 只有在不使用反向代理而直接通过端口访问的安装中,才需要开放防火墙。


1. 向代理添加 vhost​

外部代理只需将所有请求转发到工作室盒子的 :80 即可。/container/ /apps/ · /preview/ 分支已由盒子内的 web nginx 处理。

必须包含的 4 项​

漏掉时出现的症状各不相同,难以查找原因,因此建议直接复制以下示例使用。

设置漏掉时出现的症状
proxy_set_header Host $http_host路由和链接生成会错乱
Upgrade / Connection 请求头预览实时更新 (HMR) 的 WebSocket 断开,代码修改无法反映到画面
proxy_read_timeout 3600s构建聊天显示“连接错误: network error” —— 当代理因执行工具而沉默数十秒时,默认的 60 秒超时会断开流
proxy_buffering off流式响应积压在缓冲区,回答会延迟成块出现
SSE(服务器发送流)是关键

构建聊天和问答通过 SSE 实时传输。由于服务器每 25 秒发送一次心跳,代理超时只需比这更长即可,但 3600s 是经实际运营验证的值。

nginx 配置示例​

server {
listen 80;
server_name studio.company.com;

location / {
proxy_pass http://<studio-host>:80;
proxy_http_version 1.1;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s; # 에이전트 SSE(빌드 채팅) — 필수
proxy_buffering off; # 스트리밍 즉시 전달 — 필수
client_max_body_size 64M; # 사진·도면 첨부
}
}

HTTPS 可通过 certbot 等签发 —— 只需让 listen 443 ssl 块继承上述配置即可。

如果向工作室盒子的 web nginx 内添加 vhost

如果将 vhost 文件直接挂载到打包的 web nginx 容器的 conf.d,请确保文件名以 zz- 开头。因为 nginx 将按字母顺序将第一个 server 块作为默认服务器,如果名称排在前,所有不匹配的请求都会流向错误的地方,导致整个工作室崩溃(实际发生过的事故)。


2. 重新登录(必需)​

完成域名配置后,所有用户必须注销一次后重新登录。

登录 Cookie 是签发时主机的专属。通过 IP 访问并登录的会话在切换到域名后不会传递,数据请求会以 401 失败。


3. 验证​

验证项方法
工作室能打开访问 https://studio.company.com → 登录
预览能显示打开项目 → 预览画面显示,控制台无 Mixed Content
应用路径已打通访问 https://studio.company.com/container/ → 显示 404/应用列表即正常(已连接)
实时更新在聊天中修改一句话 → 预览自动更新
长时间构建构建聊天运行 1 分钟以上 → 无“连接错误”完成
部署应用数据打开已部署的应用 → 显示真实数据(无 401)

注意事项​

不要混用 IP 和域名

配置域名后,请仅通过域名访问。 使用 IP 访问的用户 Cookie 不同,部署应用数据会返回 401。

当使用 Cloudflare 时
  • WebSocket 默认支持,无需额外配置。
  • 免费通用证书仅覆盖一级子域名(studio.company.com ✅, apps.studio.company.com ❌)。
附件大小

由于会在聊天中附加现场照片和图纸,请设置 client_max_body_size 64M。 如果遗漏,大图片上传会因 413 失败。


不通过反向代理,仅附加 HTTPS​

如果没有单独的代理服务器,而要在工作室盒子上直接终止 TLS,请使用运维包中的 TLS 覆盖层。

cd /opt/kopens/plantpulse-studio-docker
cp tls/nginx-tls.conf.example tls/nginx-tls.conf # server_name 등 수정
# tls/cert.pem, tls/key.pem 배치(사내 CA 또는 공인 인증서)
docker compose -f docker-compose.yml -f docker-compose.tls.yml up -d
TLS 覆盖层示例文件仍包含旧结构

tls/nginx-tls.conf.example 中没有 /container/ 块,且注释尚未移除的 APPS_ORIGIN 和单独的端口 (5443) 仍被指引。如果直接使用,预览和部署应用地址 (/container/…)会返回 404。

目前,请在副本(tls/nginx-tls.conf)中直接添加 /container/ 块——使用上方 nginx 配置示例中的 4 种请求头,并移除前缀后转发给应用监听器即可。请勿添加 APPS_ORIGIN 行(不会被读取)。


症状 → 原因快速对照​

这些是域名部署中常见的实际情况。更广泛的内容参见 故障排除。

症状原因措施
预览和部署应用空白,控制台显示 Mixed Content工作室使用 HTTPS,但应用资源以 HTTP 请求在代理中添加 X-Forwarded-Proto $scheme 后全部改为 HTTPS
部署应用真实数据返回 401配置域名前已登录的会话注销后重新登录一次
构建聊天耗时较长时显示“连接错误: network error”代理无数据传输超时(默认 60 秒)proxy_read_timeout 3600s
代码修改不反映到预览HMR WebSocket 未升级添加 Upgrade / Connection 请求头
回答延迟成块出现proxy_buffering 已开启(默认值)proxy_buffering off
任何域名都流向错误的地方web nginx conf.d 加载顺序(首个 server 为默认服务器)将 vhost 文件名以 zz- 开头
/container/… 返回 404TLS 覆盖层副本中缺少 /container/ 块参阅上方警告
直接通过端口使用的安装中应用无法显示防火墙阻止了 5171开放防火墙后通过 curl -I http://<host>:5171/ 验证

相关文档​