メインコンテンツまでスキップ

ドメインとリバースプロキシ

IP アドレスの代わりにドメイン(特に HTTPS)で Studio をサービスするときの設定です。 この章は順番通りすべて実行する必要があります。 ひとつでも抜けると「プレビューが空白」「ビルドチャットが接続エラー」「デプロイアプリでデータが 401」といった、一見別の症状がそれぞれ現れます。


ドメインはひとつです

プレビューとデプロイアプリは Studio と同じドメインの /container/ 配下でサービスされます。

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

必要なものは DNS レコード 1 個、証明書 1 枚、vhost 1 個です。

以前はドメインが 2 個でした

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 は開ける必要がありません

アプリリスナー(: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(サーバー送信ストリーミング)が重要です

ビルドチャットと質疑応答は 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 ブロックが上記の設定をそのまま継承すれば よいです。

Studio ボックスの web nginx 内に vhost を追加する場合

パッケージ化された 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 とドメインを混在させないでください

ドメインを付与した後は、ドメインでのみアクセスしてください。IP でアクセスしたユーザーはクッキーが異なるため デプロイアプリのデータが 401 になります。

Cloudflare を前段に置く場合
  • 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 オーバーレイの例ファイルはまだ古い構成を含んでいます

tls/nginx-tls.conf.example には /container/ ブロックがなく、コメントはまだ廃止された APPS_ORIGIN と別ポート(5443)を案内しています。そのまま使用するとプレビュー・デプロイアプリのアドレス (/container/…)が 404 になります。

当面は副本(tls/nginx-tls.conf)に /container/ ブロックを直接追加してください — 上の nginx 設定例のヘッダ 4 種をそのまま使用して、プレフィックスを削除してアプリ リスナーに転送します。APPS_ORIGIN 行は入れないでください(読み込まれません)。


症状 → 原因 早見表

ドメイン展開で実際に頻繁に遭遇するものです。より広範な範囲はトラブルシューティングにあります。

症状原因対策
プレビュー・デプロイアプリが空白、コンソールに Mixed ContentStudio は 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/… が 404TLS オーバーレイ副本に /container/ ブロックがない上記の警告を参照
ポートで直接使う設置でアプリが起動しないファイアウォールが 5171 をブロックファイアウォール開放後 curl -I http://<host>:5171/ で確認

関連ドキュメント