ドメインとリバースプロキシ
IPアドレスの代わりにドメイン(特にHTTPS)でスタジオをサービス提供する際の設定です。 この章は順番にすべて実施する必要があります。 一つでも欠けると、「プレビューが空白画面」「ビルドチャットが 接続エラー」「デプロイアプリでデータが401」といった、一見異なる症状がそれぞれ発生します。
ドメインは一つです
プレビューとデプロイアプリは、スタジオと同じドメインの/container/配下で配信されます。
https://studio.company.com/ → 스튜디오 UI + API
https://studio.company.com/container/… → 프리뷰 · 배포앱
必要なのは、DNSレコード1つ、証明書1枚、vhost 1つです。
アプリを別ホストに分離しません。プレビュー・デプロイのURLがすべて相対パスのため、 80/443のみを公開するリバースプロキシ構成でそのまま動作します。
プレビュー・デプロイアプリはチャットで生成されたコード、つまり信頼できないコンテンツです。それがスタジオと 同じオリジンで動作します — オリジンを分けて得られる隔離がないという意味です。ドメインを一つに 絞る代償として受け入れた判断です。
したがって、信頼できないユーザーにアプリ作成権限を与えないでください。 ビルダーロールは社内 オペレーターのみに付与することを前提とした構成です。
準備物チェックリスト
- DNS Aレコード 1つ
- 該当ホスト名のTLS証明書
- リバースプロキシからスタジオボックスの :80 に到達可能
- スタジオボックスのファイアウォールでプロキシ → :80 を許可
アプリリスナー(: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でリアルタイム送信されます。サーバーが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 ブロックをデフォルトサーバーとして
扱うため、名前が先頭に来ると、マッチしないすべてのリクエストが誤った場所に送られ、スタジオ
全体が停止します(実際に発生した事故です)。
2. 再ログイン(必須)
ドメイン設定が完了したら、すべてのユーザーが一度ログアウトし、再度ログインする必要があります。
ログインCookieは発行時点のホスト専用です。IPでアクセスしてログインしていたセッションは、ドメインに 変更した後に引き継がれず、データリクエストが401で失敗します。
3. 確認
| 確認項目 | 方法 |
|---|---|
| スタジオが表示される | https://studio.company.com にアクセス → ログイン |
| プレビューが表示される | プロジェクトを開く → プレビュー画面が表示され、コンソールにMixed Content がない |
| アプリのパスが通っている | https://studio.company.com/container/ にアクセス → 404/アプリ一覧が表示されれば正常(接続済み) |
| リアルタイム更新 | チャットで文言を一つ修正 → プレビューが自動更新 |
| 長時間のビルド | ビルドチャットを1分以上実行 → 「接続エラー」なしで完走 |
| デプロイアプリのデータ | デプロイされたアプリを開く → 実データ表示(401なし) |
注意事項
ドメインを設定した後は、ドメインのみでアクセスしてください。IPでアクセスしたユーザーはCookieが異なるため、 デプロイアプリのデータが401になります。
- WebSocketはデフォルトでサポートされるため、追加設定は不要です。
- 無料のユニバーサル証明書は1階層のサブドメインのみをカバーします(
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/nginx-tls.conf.example には/container/ ブロックがなく、コメントがまだ削除されていない
APPS_ORIGIN と別ポート(5443)を案内しています。そのまま使用すると、プレビュー・デプロイアプリのURL
(/container/…)が404になります。
当分の間は、コピー(tls/nginx-tls.conf)に/container/ ブロックを直接追加してください — 上記の
nginx設定例のヘッダー4種をそのまま使い、接頭辞を外してアプリ
リスナーに転送すれば構いません。APPS_ORIGIN 行は追加しないでください(読み込まれません)。
症状 → 原因の早見表
ドメイン配信で実際によく発生するものです。より広範囲な内容はトラブルシューティングを参照してください。
| 症状 | 原因 | 対処 |
|---|---|---|
プレビュー・デプロイアプリが空白画面、コンソールにMixed Content | スタジオはHTTPSなのにアプリのアセットがHTTPでリクエストされる | プロキシにX-Forwarded-Proto $scheme を追加し、全体をHTTPSにする |
| デプロイアプリで実データが401 | ドメイン設定前にログインしたセッション | ログアウトして再ログインを1回 |
| ビルドチャットが長時間かかると「接続エラー: network error」 | プロキシの無送信タイムアウト(デフォルト60秒) | proxy_read_timeout 3600s |
| コード修正がプレビューに反映されない | HMR WebSocketがアップグレードされていない | Upgrade / Connection ヘッダーを追加 |
| 回答がまとまって遅れて表示される | proxy_buffering が有効(デフォルト) | proxy_buffering off |
| 任意のドメインが誤った場所に送られる | web nginxのconf.d読み込み順序(最初のserver がデフォルトサーバー) | vhostファイル名をzz- で始める |
/container/… が404 | TLSオーバーレイのコピーに/container/ ブロックがない | 上記の警告を参照 |
| ポートで直接使用する構成でアプリが表示されない | ファイアウォールで5171がブロックされている | ファイアウォールを開放後、curl -I http://<host>:5171/ で確認 |
関連ドキュメント
- インストール — ポート・ファイアウォール
- シークレット管理 — 環境変数変更後の反映方法
- トラブルシューティング