ドメインとリバースプロキシ
IP アドレスの代わりにドメイン(特に HTTPS)で Studio をサービスするときの設定です。 この章は順番通りすべて実行する必要があります。 ひとつでも抜けると「プレビューが空白」「ビルドチャットが接続エラー」「デプロイアプリでデータが 401」といった、一見別の症状がそれぞれ現れます。
ドメインはひとつです
プレビューとデプロイアプリは Studio と同じドメインの /container/ 配下でサービスされます。
https://studio.company.com/ → 스튜디오 UI + API
https://studio.company.com/container/… → 프리뷰 · 배포앱
必要なものは DNS レコード 1 個、証明書 1 枚、vhost 1 個です。
2026-08-23 より前は、アプリを別ホスト(studio-apps.company.com)に分離し、そのアドレスを
APPS_ORIGIN または環境設定の「アプリオリジン」で通知する必要がありました。その設定はなくなりました。
廃止した理由は、その値ひとつが空だとサーバーがプレビュー URL を 요청호스트:5171 で生成するのに、
80/443 だけを公開するリバースプロキシ構成ではブラウザがそこに接続できず、ライブプレビューが
丸ごと空白になったからです。相対パスだけを使えば、最初から間違いようがありません。
.env または環境設定に古い APPS_ORIGIN 値が残っていても、今は 読み込まれません。
プレビュー・デプロイアプリはチャットで生成されたコード、つまり信頼できないコンテンツです。以前の構成はオリジンを 分離して、その JavaScript が Studio ログイントークンにアクセスできないようにしていました。今は同じ オリジンで動作するため、その隔離がなくなりました。 ドメインをひとつに減らす代償として受け入れた判断です。
したがって 信頼できないユーザーにアプリ作成権限を与えないでください。 ビルダーロールは社内 オペレータにのみ付与することを前提とした構成です。
準備物チェックリスト
- DNS A レコード 1 個
- 該当ホスト名の TLS 証明書
- リバースプロキシから Studio ボックスの :80 に到達可能
- Studio ボックスのファイアウォールでプロキシ → :80 を許可
アプリリスナー(:5171)は Studio ボックス内の web nginx が /container/ · /apps/ · /preview/
を転送するため、外部に公開する必要がありません。 リバースプロキシなしでポートに直接アクセスする
インストールの場合のみ、ファイアウォールを開いてください。
1. プロキシに vhost を追加
外側のプロキシは すべてを Studio ボックスの :80 に転送するだけで構いません。/container/ ·
/apps/ · /preview/ の振り分けはボックス内の web nginx がすでに処理します。
必ず入れるべき 4 つの設定
抜けたときに現れる症状が異なるため、原因特定が難しくなります。下記の例をそのままコピーして 使用することをお勧めします。
| 設定 | 抜けるとどうなるか |
|---|---|
proxy_set_header Host $http_host | ルーティング・リンク生成がずれます |
Upgrade / Connection ヘッダ | プレビューのホットモジュールリプレイスメント(HMR)ウェブソケットが切れて、コード修正が画面に反映されません |
proxy_read_timeout 3600s | ビルドチャットが「接続エラー: network error」 — エージェントがツール実行で数十秒沈黙すると、デフォルトの 60 秒タイムアウトがストリームを切ります |
proxy_buffering off | ストリーミングレスポンスがバッファに溜まり、回答が大きなかたまりで遅れて表示されます |
ビルドチャットと質疑応答は 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 コンテナの conf.d に直接 vhost ファイルをマウントする場合は、ファイル名を
zz- で開始してください。nginx はアルファベット順で最初の server ブロックをデフォルトサーバーとするため、
名前が先だと マッチしないすべてのリクエストが別の場所に落ちて Studio
全体が死にます(実際に発生した事故です)。
2. 再ログイン(必須)
ドメイン設定が済んだら、すべてのユーザーが一度ログアウトしてから再度ログインする必要があります。
ログインクッキーは発行時点のホスト専用です。IP でログインしておいたセッションは、ドメインに変更した後 転送されないため、データリクエストが 401 で失敗します。
3. 確認
| 確認項目 | 方法 |
|---|---|
| Studio が起動する | https://studio.company.com にアクセス → ログイン |
| プレビューが起動する | プロジェクトを開く → プレビュー画面表示、コンソールに Mixed Content がないこと |
| アプリパスが通っている | https://studio.company.com/container/ にアクセス → 404/アプリ一覧が表示されれば正常(接続済み) |
| リアルタイム更新 | チャットで文句を 1 つ修正 → プレビューが自動更新 |
| 長いビルド | ビルドチャット 1 分以上実行 → 「接続エラー」なく完了 |
| デプロイアプリのデータ | デプロイされたアプリを開く → 実データ表示(401 なし) |
注意事項
ドメインを付与した後は、ドメインでのみアクセスしてください。IP でアクセスしたユーザーはクッキーが異なるため デプロイアプリのデータが 401 になります。
- WebSocket はデフォルトでサポートされているため、別途設定は必要ありません。
- 無料のユニバーサル証明書は 1 段階のサブドメインのみをカバーします(
studio.company.com✅,apps.studio.company.com❌)。
現場の写真・図面をチャットに添付するため client_max_body_size 64M を設定してください。
抜けると大きな写真のアップロードが 413 で失敗します。
リバースプロキシなしで HTTPS だけを付与
別のプロキシサーバーがなく、Studio ボックスで直接 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/nginx-tls.conf.example には /container/ ブロックがなく、コメントはまだ廃止された
APPS_ORIGIN と別ポート(5443)を案内しています。そのまま使用するとプレビュー・デプロイアプリのアドレス
(/container/…)が 404 になります。
当面は副本(tls/nginx-tls.conf)に /container/ ブロックを直接追加してください — 上の
nginx 設定例のヘッダ 4 種をそのまま使用して、プレフィックスを削除してアプリ
リスナーに転送します。APPS_ORIGIN 行は入れないでください(読み込まれません)。
症状 → 原因 早見表
ドメイン展開で実際に頻繁に遭遇するものです。より広範な範囲はトラブルシューティングにあります。
| 症状 | 原因 | 対策 |
|---|---|---|
プレビュー・デプロイアプリが空白、コンソールに Mixed Content | Studio は HTTPS だがアプリアセットが HTTP でリクエストされている | プロキシに X-Forwarded-Proto $scheme を追加してすべてを HTTPS に |
| デプロイアプリでリアルデータが 401 | ドメイン付与前にログインしたセッション | ログアウト後に再度ログイン 1 回 |
| ビルドチャットが長いと「接続エラー: network error」 | プロキシの無送信タイムアウト(デフォルト 60 秒) | proxy_read_timeout 3600s |
| コード修正がプレビューに反映されない | HMR ウェブソケットがアップグレードされていない | Upgrade / Connection ヘッダを追加 |
| 回答が大きなかたまりで遅れて表示される | proxy_buffering がオン(デフォルト) | proxy_buffering off |
| どのドメインでも別の場所に落ちる | web nginx conf.d 読み込み順序(最初の server がデフォルトサーバー) | vhost ファイル名を zz- で開始 |
/container/… が 404 | TLS オーバーレイ副本に /container/ ブロックがない | 上記の警告を参照 |
| ポートで直接使う設置でアプリが起動しない | ファイアウォールが 5171 をブロック | ファイアウォール開放後 curl -I http://<host>:5171/ で確認 |
関連ドキュメント
- インストール — ポート・ファイアウォール
- シークレット管理 — 環境変数変更後の反映方法
- トラブルシューティング