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

インストール

PlantPulse Studio を顧客サーバー1台にインストールする手順です。 Docker コンテナ4種(Web・サーバー・ビルダーサイドカー・Docker プロキシ)で構成され、インストールスクリプトが Docker のインストールから起動まで自動的に処理します。

PostgreSQL はスタックに含まれません

外部 PG を使用します — プラットフォームが使用するものと同じ PG を共用できます。以前はバンドル コンテナを起動するモードがありましたが、廃止されました(2026-08-28) — 1台のサーバーで 5432 を 巡って競合する事故が実際に発生しました。

インターネットに接続できない閉域網の場合は、このドキュメントの代わりに閉域網インストールを参照してください。


1. 前提要件​

サーバー仕様​

項目最小推奨備考
CPU4 コア8 コア以上アプリセッションごとにビルドが実行されます
メモリ8 GB16 GB 以上下記の表を参照
ディスク50 GB の空き100 GB 以上コンテナイメージのみで約 6 GB
OSLinux (x86_64)RHEL 9 / Rocky 9 / Ubuntu 22.04 以上systemd + Docker が動作すれば問題ありません

メモリ算出の根拠 — スタックが固定で確保する上限値です。

コンテナメモリ上限
studio-server (オーケストレーター)2 GB
agent-server (ビルダーサイドカー)2 GB (AGENT_SERVER_MEMORY で調整)
studio-web (nginx)256 MB
docker-proxy (Docker 窓口)128 MB
アプリセッションコンテナ 1つあたり2 GB

アプリセッションコンテナは、ユーザーがプロジェクトを開くたびに1つ起動し、30分間使用されないと自動 回収されます。同時作業者数分の 2 GB を追加で見込んでください。

同時ユーザー3〜5名が目標なら

16 GB メモリ・8 コア・100 GB ディスクを基準にすれば余裕があります。

ソフトウェア​

  • Docker Engine + Docker Compose v2 (v2.22 以上) インストールされていない場合、ワンラインインストールスクリプトが自動的にインストールします。
  • curl、tar (ほとんどのディストリビューションに標準搭載)

ポートとファイアウォール​

スタックは host ネットワークで動作します。つまりコンテナのポートがホストにそのまま開放されるため、 アクセス制御はサーバーのファイアウォールのみで行われます。

ポート用途ファイアウォール
80スタジオ UI (nginx)開放
5171アプリリスナー — プレビュー・配信アプリ・QR アクセス開放(必須)
5170スタジオ APIWeb が内部プロキシ — 開放不要(診断用)
8000ビルダーサイドカー(agent-server)ループバック専用 — 絶対に開放禁止
5172MCP ツールブリッジループバック専用 — 絶対に開放禁止
2375Docker デーモン窓口(docker-proxy)127.0.0.1 のみにバインド — スタックで唯一 host ネットワークではないコンテナ
5171 を塞ぐとプレビューと配信アプリが開けません

プレビュー(/preview/…)と配信アプリ(/apps/…)は、セキュリティ境界のためスタジオとは別オリジン (デフォルト 5171 ポート)で配信されます。チャットで作成したアプリの JavaScript がスタジオのログイン トークンにアクセスできないようにする仕組みです。5171 を開放しないと画面が真っ白に見えます。

8000・5172 には認証がありません

この2つのポートは内部コンポーネント間の通信専用であり、認証手順がありません。外部に露出すると、全体の ユーザーワークスペースを読み書きできるようになります。スタックはデフォルトでループバックのみに バインドしますが、ファイアウォールでも絶対に開放しないでください。

レジストリアクセス​

イメージは KOPENS レジストリ(docker.kopens.io)から取得します。インストール前に一度ログインしてください。 アカウントは KOPENS 運用チームが発行します。

docker login docker.kopens.io

2. データベース準備​

スタジオは外部 PostgreSQL を使用します。 プラットフォームが使用するものと同じ PG を共用できます。

DATABASE_URL は必須です

空の場合、インストールはその場で停止し、何が空いているかを通知します — もっともらしいデフォルト値を 捏造しません。 もっともらしいデフォルト値が誤った場所を指して事故が発生したことがあるためです。

DATABASE_URL=postgres://`<user>`:`<password>`@`<db-host>`:5432/`<db-name>`

データベースとアカウントを先に作成します​

🔴 サーバーは「存在する」データベースにマイグレーションするだけです。DB とロールは作成しません。 作成するスクリプトが別途用意されています。

# .env 의 DATABASE_URL 이 가리키는 DB · 역할을 만든다
bin/provision-platform-db.sh

# 관리자 계정을 따로 줘야 하는 경우
ADMIN_URL=postgres://`<관리자>`:`<password>`@`<호스트>`:5432/postgres bin/provision-platform-db.sh

# 무엇을 할지 보기만 한다
DRYRUN=1 bin/provision-platform-db.sh

AI 側と同じルールです。


3. インストール(ワンライン・推奨)​

サーバーに root でログインし、1行実行します。スクリプトが Docker 確認・インストール → パッケージ取得 → .env 作成 → スタック起動までを実行します。

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo bash

インストール先は /opt/kopens/plantpulse-studio-docker で、以降のすべての運用コマンドはこのディレクトリで 実行します。

値を事前に指定して無人インストール​

環境変数は**bash の前に**付ける必要があります。パイプ経由で渡されます。

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh \
| sudo PLATFORM_API_TARGET=https://192.168.0.41 \
DATA_ROOT=/data1/pp-studio \
PS_ANTHROPIC_API_KEY=sk-ant-... \
bash

値を対話式で尋ねる​

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo INTERACTIVE=1 bash
⌨️ 新規ボックスへのインストール — 最初から「Ready」まで 2分6秒。実際の実行を録画し、遅延までそのまま再現しています(イメージ取得の静的区間は折りたたまれています)
この画面は「新規」ボックスでのみ表示されます

既にインストール済みのサーバーで再実行すると、サイドカーに値が存在するためプロンプト全体をスキップします。 上記の画面はクリーンなボックスへの初回インストールです。

尋ねるのは5つだけです(2026.09 以降)。残りの7つはデフォルト値で設定し、設定された値をインストール終了時にリストで表示します — 隠すのではなく、表示して進みます。

順序尋ねる項目変数
1プラットフォーム API サーバー (https://…)PP_API_URL
2プラットフォーム API トークン (X-API-Key)PP_API_TOKEN
3AI ゲートウェイアドレス — /v1 まで含むPI_LLM_URL
4AI ゲートウェイキー (LiteLLM マスターキー)PI_LLM_API_KEY
5AI モデル名 — ゲートウェイに登録された名前AI_MODEL
これらの値を準備してください — ないとインストールが中断されます

必須値が空の場合、インストールは停止します。 「インストールは完了したように見えるのにスタックが起動しない」状態を 防ぐための意図的な動作です。DATABASE_URL は尋ねません — PostgreSQL はスタックに同梱され、 インストールが自動的に設定します。

尋ねずにデフォルト値を使用する7つ — DATA_ROOT(/var/lib/pp-studio)・AI_PROVIDER(openai-compatible)・ PP_LANG(en)・PP_TZ(Asia/Seoul)・APPS_PORT(5171)・REGISTRY(docker.kopens.io/ps)・ PP_IMAGE_TAG(現在のカレンダーバージョン)。

モデル名を尋ねる理由

ゲートウェイが提供していないモデル名を指定すると、間違ったキーと同様に失敗します。そのためデフォルト値から 外し、尋ねる項目にしました。

変更するには、環境変数で指定するか、PP_ADVANCED=1 で実行してすべて尋ねるようにできます。

PS_ANTHROPIC_API_KEY は現在尋ねません

クラウド Claude を使用する場合にのみ必要な値ですが、この製品はゲートウェイが前提のため、事実上全員が Enter で スキップしていた質問でした。機能はそのままで、設定方法は3通りです — インストール時に環境変数で、 後で bin/passwd.sh PS_ANTHROPIC_API_KEY(値を省略するとプロンプトで受け取り、コマンドラインに残りません)、 または画面の設定 > AI です。PP_ADVANCED=1 でも尋ねません。

再実行しても安全です

同じサーバーでインストールスクリプトを再実行すると、コードのみが更新され、.env とローカルバックアップ(dist/)は 保持されます。アップグレード用途としてそのまま使用できます。

インストールスクリプトが 404 や古いバージョンを返す場合

CDN キャッシュが残っている可能性があります。URL の後ろに ?v=$(date +%s) を付けて再取得してください。

値を間違えて指定するとインストール前に停止します​

マシンに触れる前に — Docker をインストールする前にも — 受け取った資格情報で実際の呼び出しを一度ずつ実行します。 プラットフォームは GET /api/v5/site?limit=1、ゲートウェイは GET /v1/models です。

⌨️ 間違ったゲートウェイキーで実行 — プラットフォームトークンが 401 で拒否され、インストールは開始せず停止します。後方の「503」は警告としてのみ残ります

拒否された場合のみ停止します。「確認できなかった」場合は停止しません。

応答判定インストール
2xx受け入れ続行
401・403資格情報が誤り中断
400インストールスクリプトのリクエストが不正 — 製品不具合のためご連絡ください中断
5xx・到達不能判定不能警告のみ、続行

5xx を 401 と同じ欄に入れなかったのは意図的です — 負荷のかかったプラットフォームが 503 を返し、3分後に 同じトークンが 401 を返した事例がありました。点検中またはスタジオより遅れて起動するゲートウェイを 「誤ったキー」と断定すると、正常なインストールが拒否されます。

モデル名も一緒に確認します。 ゲートウェイの /v1/models 応答を読み、AI_MODEL がそのリストに含まれるか 確認し、ない場合は提供しているリストを表示して停止します。 リストを読み取れなかった場合は判定しません — 答えが空なのに「ない」と言うことは、失敗しようがない検査と同じ虚偽だからです。

検査をスキップする場合 — PP_SKIP_CRED_CHECK=1

プレースホルダー資格情報でインストール自体のみをテストするためのスイッチです(製品のリリースゲートがこの経路を 使用します)。運用インストールでこの値を有効にすることは、初回使用時の失敗をインストール時点に先送りするだけです。


4. インストール(手動)​

パッケージを既に取得している場合、または .env を直接作成する場合です。

cd /opt/kopens/plantpulse-studio-docker
sudo cp .env.example /etc/kopens/plantpulse-studio.env
sudo vi /etc/kopens/plantpulse-studio.env # 아래 표를 보고 값 채우기
sudo chmod 600 /etc/kopens/plantpulse-studio.env
bash bin/up.sh
設定の原本は /etc/kopens/plantpulse-studio.env の1つです

環境変数ファイルはインストールディレクトリ内ではなくrepo ツリー外の /etc/kopens/plantpulse-studio.env に配置します。権限は 0600 です。platform・ai・studio の3製品が同じ規約で /etc/kopens/plantpulse-<product>.env を使用します。

インストールディレクトリルートの .env は旧パスです。compose も他のスクリプトも現在はその ファイルを読み込まないため、そこを編集してもスタックは変わりません。既存インストールの .env は bin/install.sh が新しいパスへ移動します(新規作成はしません — 新規作成すると DB は旧 パスワード、env は新デフォルト値となり、次回再起動時に停止します)。

環境変数の主要項目​

項目説明デフォルト値
REGISTRYイメージレジストリ。空にすると pull せずローカルイメージのみ使用(エアギャップ)docker.kopens.io/ps
PP_IMAGE_TAGイメージタグ。空にすると VERSION のカルバーに従います。固定するにはスナップショットタグ(2026.09-20260911)推奨(空)
DATA_ROOTすべてのデータ(ワークスペース・ビルド・状態・DB)が保存されるパス/var/lib/pp-studio
PLATFORM_API_TARGET実データ・認証を委任する PlantPulse プラットフォームアドレスhttps://192.168.0.41
APPS_PORTアプリリスナーポート(プレビュー・配信アプリ)5171
PP_LANGWeb のデフォルト言語 ko / enen
PP_TZタイムゾーン(IANA ID)。「今日・昨日・先週」の解釈基準Asia/Seoul
STUDIO_CORS_ORIGINS別ドメインから API を呼ぶ場合のみ指定。デフォルトはブロック空
DATABASE_URL外部 PostgreSQL 接続アドレス — 上記2節参照空 (必須)
PI_LLM_API_KEY・PP_API_TOKEN などAI・プラットフォームキー — シークレット管理参照空 (必須)
アカウントとロールは環境変数で渡しません

アカウントは環境変数で渡しません。 サーバーにアカウントが1つもない場合、ブートストラップ管理者を DB に作成し、その後はアプリの 環境設定 → ユーザー管理でアカウントを追加・削除し、ロール(管理者 / ビルダー / ビューア)を付与します。 下記の7. 初回ログインを参照してください。

韓国語の現場では PP_LANG=ko を直接設定してください

ワンラインインストールが作成する .env には PP_LANG・PP_TZ 行がなく、デフォルト値(en / Asia/Seoul)が 適用されます。韓国語で表示するには .env に PP_LANG=ko を追加し、bash bin/restart.sh してください。

.env を変更した後は必ず bin/restart.sh

docker restart は .env を再読み込みしません。値が反映されないまま「なぜ変わらないのか」を しばらく探すことになる典型的な落とし穴です。詳細はシークレット管理にあります。


5. スタック構成の確認​

インストールが完了すると、コンテナ群が起動しているはずです。PostgreSQL はここにはありません — 外部 PG を使用します。

コンテナ役割
plantpulse-studio-webスタジオ UI(nginx :80) — 静的画面 + API プロキシ
plantpulse-studio-serverオーケストレーター(:5170) — エージェント・セッション・配信・アプリリスナー(:5171)
plantpulse-studio-agent-serverビルダーサイドカー — アプリコードを作成するコーディングエンジン
plantpulse-studio-docker-proxyDocker デーモン窓口。127.0.0.1 のみに開放されます
オーケストレーターは Docker ソケットを直接掴みません

docker.sock をサーバーにマウントせず、Docker プロキシを経由します。 セッションコンテナを作成・ 削除するにはデーモンが必要ですが、ソケットをそのまま渡すとそれはホスト全体の権限と同等です。

プロキシのみhost ネットワークを使用せず 127.0.0.1:2375 に公開します。host ネットワークだった場合、 2375 はファイアウォール以外に何も守らない開放デーモンになっていたでしょう。

Docker プロキシは「脱出を防ぐ境界」ではありません

セッションコンテナを作成するには POST /containers/create が必要で、それを呼び出せる 側は / をマウントしたコンテナも作成できます。 プロキシの制御単位は エンドポイントでありパラメータではありません。

このプロキシが実際に行うことは2つです — 使用しない API サーフェス(ボリューム・シークレット・設定・ スウォーム・ノード・プラグイン・システムイベント)を切り落とすこと、そしてデーモンアクセスを1点に 集約して監査可能にすること。許可範囲は studio-server が実際に使用するものだけに 絞られています(コンテナ・イメージ・ビルド・exec・ネットワーク・レジストリログイン)。

したがって、このスタックを信頼境界の内側に配置してください。 アプリを作成する人が即座にホストに対する 権限を持つものとして運用する必要があります。

これに加えて、ユーザーがプロジェクトを開くとアプリセッションコンテナがプロジェクトごとに1つ起動します。 スタックコンテナではなく、サーバーが必要時に作成し、アイドル30分後に回収します。


6. 起動確認​

cd /opt/kopens/plantpulse-studio-docker

bash bin/status.sh # 컨테이너 상태 + 헬스 + 세션 컨테이너 수
curl -s localhost:5170/health

インストール直後は、総合点検スクリプトを一度実行することを推奨します。ヘルス・Web 応答・実際の ログイン・セッションランタイムイメージ・コンテナ状態をすべて検査し、1つでも失敗するとエラーで終了します。

bash bin/smoke-install.sh
✓ health
✓ client-config → {"lang":"ko",...}
✓ web 200
✓ 로그인(부트스트랩 계정)
✓ 세션 런타임 이미지
✓ 컨테이너 running(...)
✅ 설치 스모크 통과
セッションランタイムイメージ

アプリセッションコンテナは plantpulse-studio-runtime イメージを使用します。bin/up.sh がローカルにない場合 取得してタグ付けしますが、失敗すると ⚠️ 세션 런타임 이미지 없음 警告が表示され、プロジェクトを開く操作が 失敗します。この場合はレジストリログイン状態を確認し、bash bin/up.sh を再実行してください。

既にローカルにある場合、up.sh は変更しません — 新しいバージョンに変更するには bin/update.sh です。


7. 初回ログイン​

ブラウザで http://<server-ip>/ にアクセスします。

アカウントが1つもない状態でサーバーが初めて起動すると、ブートストラップ管理者を DB に作成します。

項目値
ユーザー名admin
パスワードadmin123!

起動ログにも出力されます — 부트스트랩 관리자 생성: admin — 로그인 후 비밀번호를 바꿀 것。

最初にこのパスワードを変更してください

すべてのインストールで同じ値です。ログインしたらすぐに環境設定 → ユーザー管理で変更してください (パスワードリセット、6文字以上)。環境変数ファイルを編集しても変更されません — サーバーは ログイン時に①DB → ②環境変数の順で確認し、DB で見つかればそこで終了します。

ログイン後のタスク:

  1. 環境設定 → ユーザー管理 — ブートストラップ管理者のパスワード変更、現場ユーザーアカウント作成、 ロール(管理者 / ビルダー / ビューア)指定
  2. パスワード・API キー変更 — DB アカウントと AI キーを bin/passwd.sh で一度にローテーション。コミッショニング時に一度だけ行えば十分です
  3. 環境設定 → AI — AI プロバイダーとキーの接続状態確認
  4. 環境設定 → プラットフォーム — プラットフォームアドレス・キー接続確認(実データ取得に必要)

詳細な画面説明ははじめにと 環境設定(管理者)にあります。​

8. 日常運用コマンド​

すべてのコマンドはインストールディレクトリ(/opt/kopens/plantpulse-studio-docker)で実行します。

bash bin/up.sh # 시작(레지스트리에서 최신 이미지 pull 포함). 종료 코드 0 = «준비됨»
bash bin/down.sh # 중지 — 데이터는 그대로 보존, 세션 컨테이너도 정리
bash bin/restart.sh # 재기동(.env 변경 반영)
bash bin/status.sh # 상태 요약
bash bin/logs.sh # 서버 로그 팔로우(기본 studio-server)
bash bin/logs.sh studio-web # 특정 서비스 로그
bash bin/update.sh # 이미지 갱신 + 재기동 → [업데이트](#9-アップデート)
bash bin/remove.sh # 컨테이너·네트워크 제거. **데이터는 보존이 기본**
start.sh・stop.sh という旧名称も引き続き動作します

3製品(Platform・AI・Studio)が同じ名前・同じ意味の共通動詞を使用するよう整理されました — up・down・restart・status・logs・update・remove。

旧名称は削除していません。bin/start.sh と bin/stop.sh は引き続き同じ処理を行います (CI がリモートホストでその名前を直接呼び出します)。既存のラン ブックを一度に修正する必要はありません。

down.sh が compose のみを呼び出さない理由

Studio サーバーがアプリを開くときに作成するセッションコンテナ(plantpulse-studio=1 ラベル)は compose が 管理しません。docker compose down のみを呼び出すと、それらはそのまま稼働し続けます — 「停止したのにコンテナが生きている」という状態になる箇所です。down.sh はそれらも整理します。

remove.sh はデータを削除しません — 削除するには明示が必要です
bash bin/remove.sh # 컨테이너·네트워크만. 데이터 그대로
bash bin/remove.sh --volumes # 데이터까지 (확인을 묻습니다)
bash bin/remove.sh --volumes --yes # 자동화용 — 묻지 않습니다

このスタックの実データは named volume ではなく DATA_ROOT バインドマウント(デフォルト /var/lib/pp-studio)にあります — PG データ・ワークスペース・ビルド成果物・状態。 docker compose down -v では削除されませんが、オペレーターが「削除」と言う場合、それまで 意味することが多いです。元に戻せないため、明示的に要求された場合のみ操作します。

セッションコンテナのみを個別に表示する場合、

docker ps --filter label=plantpulse-studio=1

9. アップデート​

bin/update.sh がイメージを再取得し、再起動まで行います。インストールスクリプトを再実行すると 運用スクリプトも一緒に更新されます(.env・バックアップは保持)。

=== "イメージのみ更新"

cd /opt/kopens/plantpulse-studio-docker
bash bin/update.sh
up.sh(旧 start.sh)のみでは「セッションランタイム」が旧イメージのまま残ります

up.sh は compose サービスのイメージを取得します。しかしユーザーアプリが実際に動作する セッションランタイムイメージは compose サービスではないため compose pull の対象にならず、 up.sh はそれをローカルにない場合のみ取得します — 既にあればそのままにします。

そのため up.sh のみを実行すると、他は新イメージなのにセッションランタイムだけ静かに旧バージョンのまま 残ります。update.sh はその1つを強制的に再取得することが up.sh との違いです。

=== "パッケージまで更新"

curl -fsSL https://product.kopens.io/plantpulse-studio/install.sh | sudo bash

バージョン固定​

バージョン表記は YYYY.MM 形式です(例: 2026.08)。自動更新を望まない運用環境では .env にタグを固定してください。

TAG=2026.08
アップデート前にはバックアップ

bash bin/backup.sh を先に実行しておいてください。手順はバックアップと復元にあります。

イメージ署名検証(任意)​

配布されたイメージが KOPENS によって署名されたものであるか確認できます。cosign がインストールされている必要があります。

cd /opt/kopens/plantpulse-studio-docker
bash bin/verify-images.sh
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-server:2026.08
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-web:2026.08
[verify] ✅ docker.kopens.io/ps/plantpulse-studio-runtime:2026.08

次のステップ​