Core · デプロイと運用

PM2(app-installer)でデプロイする

app-installer はデプロイ用アーカイブをサーバーにインストールし、PM2 でアプリを実行します。以降のバージョン切り替え、バックアップ、ロールバックも管理します。ソースコードは開発マシンに置き、サーバーの実行時設定と業務データはリリースとは別に保存します。

前提条件

以下の IP と HTTP による直接アクセスの例は、信頼できるネットワーク内でのデプロイ確認用です。公開ネットワークや信頼できないネットワークから管理者としてサインインする前に、ドメイン、HTTPS、リバースプロキシを設定してください。 開発マシンには Node.js 24 と pnpm 11 が必要です。サーバーには Node.js 24 と、グローバルにインストールした PM2 4.3 以上が必要です。コマンドは Bash を使い、Linux x64/glibc、SQLite、単一インスタンスを例にしています。別のデータベースでは、対応するドライバーをソースに追加して再ビルドし、インストール時に接続設定を指定してください。

例ではアプリ名 my-app、SSH 接続先 deploy@server、インストール先 /srv/nocobase/my-app、PM2 プロセス名 nocobase-my-app、ポート 13000、アプリのパス /main を使います。実際の値に置き換え、複数のアプリには別々のディレクトリ、ポート、プロセス名を指定してください。

コマンドは @nocobase/app-installer@beta を使い、サーバーの既存の npm registry 設定に従って、すべてサーバーで実行します。設定した registry からインストーラーを取得できる必要があります。既存環境でインストーラーのバージョンを固定する場合は、@beta を指定バージョンに置き換えてください。開発マシンはビルド、アーカイブ作成、アップロードを担当します。

エージェントを使う

アプリのソースディレクトリで開発用エージェントを使います。まだアプリがなければ先に作成してください。サーバーへのアクセスを準備し、パスワードや認証情報はプロンプトに書かず安全な方法で提供します。アプリ付属のデプロイ Skill に、そのバージョンに対応する手順があります。

初回デプロイ

対象の情報を置き換えて使います:

プレーンテキスト
開発マシンで現在のアプリをビルドしてアーカイブを作成・アップロードし、サーバーで app-installer を実行して初回インストールしてください。プロセスは PM2 で管理してください。

サーバー:<SSH ユーザーとアドレス>
インストール先:<サーバー上の絶対パス>
アクセス URL:<アプリのパスを含む完全な URL>
データベース:新しい SQLite。開発データやサンプルデータは取り込まない

管理者のサインインを設定し、設定と業務データをリリースとは別に保存してください。
サインインと主要な業務操作を確認してから、アプリを再起動してデータが残ることを確認してください。
アクセス URL、確認結果、サーバー起動時の自動起動が設定済みかを教えてください。

新しいバージョンをデプロイする

コードを更新し、テストを通したアプリのソースディレクトリで使います:

プレーンテキスト
開発マシンで現在のプロジェクトの新しいバージョンをビルドしてアーカイブを作成・アップロードし、元のサーバーで app-installer を実行して更新してください。

サーバー:<SSH ユーザーとアドレス>
元のインストール先:<サーバー上の絶対パス>
停止可能な時間帯:<メンテナンス時間帯>

元の URL、設定、シークレット、データベース、アップロードファイルを保持し、再初期化しないでください。
バージョンの変更内容とバックアップの範囲を確認してからデプロイしてください。
完了後に既存データ、ユーザー権限、新機能を確認してください。失敗した場合は、復旧結果とデータへの影響を説明してください。

エージェントも同じ分担で実行します。開発マシンでビルド、アーカイブ作成、アップロードを行い、サーバーに接続して app-installer と PM2 を実行します。エージェントと手動コマンドはどちらか一方を選び、どちらも後述のアクセスと永続性の確認を行ってください。

手動でデプロイする

開発マシンのターミナルはビルド、アーカイブ作成、アップロードを担当します。サーバーのターミナルはインストール、新しいバージョンのデプロイ、状態確認、ロールバック、PM2 管理に使います。両方を開いておき、すべての @nocobase/app-installer コマンドをサーバーのターミナルで実行してください。

各コマンドの前に実行場所を示します。パスワード変数の設定、インストール、変数の解除は同じターミナルで行います。絶対パスを指定するコマンドではインストール先への移動は不要です。相対パス storage/exports/dist.tar.gz は、開発マシンのアプリのソースディレクトリで使ってください。

アプリを作成してディレクトリに移動する

開発マシン · アプリの親ディレクトリ
pnpm create @nocobase/app@beta my-app --template-tag=beta
cd my-app

既存のアプリではソースディレクトリに移動し、ビルド前にテストが通ることを確認します。

デプロイ用アーカイブをビルドする

開発マシン · アプリのソースディレクトリ my-app/
pnpm build --target linux-x64 --node-version 24 --tar

生成される storage/exports/dist.tar.gz には dist/、本番用の依存関係、設定テンプレートが入り、開発用データベース、シークレット、アップロードファイルは入りません。サーバーでこのアーカイブに対して pnpm install を実行する必要はありません。

対象のアーキテクチャ、libc、Node のメジャーバージョンをサーバーに合わせます。ARM64/glibc は linux-arm64、Alpine などでは対応する musl target を使います。

サーバーを準備する

アプリを実行するサービスアカウントでサーバーに接続します:

開発マシン · 任意のディレクトリ
ssh deploy@server

実行環境を確認します:

サーバー · 元のサービスアカウント、任意のディレクトリ
node --version
node -p "process.platform + '-' + process.arch"
command -v pm2

PM2 がなければサーバーにグローバルインストールします:

サーバー · 元のサービスアカウント、任意のディレクトリ
npm install -g pm2

管理者が現在のサービスアカウント用に新しい空のディレクトリを用意します:

サーバー · 元のサービスアカウント、任意のディレクトリ
sudo mkdir -p /srv/nocobase/my-app
sudo chown "$(id -u):$(id -g)" /srv/nocobase/my-app

以降のインストール、状態確認、PM2 管理も同じサービスアカウントで行います。対象は新規または空のディレクトリにしてください。再インストールのために既存環境を消さないでください。

サーバー上でインストールする

開発マシンからアーカイブをアップロードし、サーバーのターミナルに切り替えてインストールします:

開発マシン · アプリのソースディレクトリ my-app/
scp storage/exports/dist.tar.gz deploy@server:/tmp/my-app.tar.gz

サーバーでパスワード変数を設定し、インストールします。YOUR_SERVER_IP を実際の IP に置き換えてください:

サーバー · 元のサービスアカウント、任意のディレクトリ
read -r -s -p 'Initial admin password: ' MY_APP_ADMIN_PASSWORD
export MY_APP_ADMIN_PASSWORD
サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta install /srv/nocobase/my-app \
  --archive /tmp/my-app.tar.gz \
  --origin http://YOUR_SERVER_IP:13000 \
  --base-path /main \
  --host 0.0.0.0 \
  --port 13000 \
  --name nocobase-my-app \
  --dialect sqlite \
  --set app.sampleData=false \
  --set-from-env users.initialAdmin.password=MY_APP_ADMIN_PASSWORD \
  --json
サーバー · 元のサービスアカウント、任意のディレクトリ
unset MY_APP_ADMIN_PASSWORD

インストーラーがアーカイブを展開し、設定を初期化し、マイグレーションとシードを実行して、PM2 プロセスを登録・起動します。初期管理者パスワードはユーザーテーブルが空の場合だけ適用され、既存アカウントはリセットしません。

--set-from-env はサーバーの現在のターミナルからパスワード変数を読み取ります。パスワードを --set に直接書かないでください。

アクセス URL を設定する

上の例はサーバーの 13000 ポートで直接待ち受けるため、ファイアウォールやセキュリティグループでアクセスを許可します。--origin はパスを含まず、--base-path でパスを指定します。アクセス先は http://YOUR_SERVER_IP:13000/main/ です。

ドメイン、HTTPS、同じサーバーのリバースプロキシを使う場合は、初回インストールの対応する引数を変更します:

プレーンテキスト
--origin https://apps.example.com
--base-path /main
--host 127.0.0.1
--port 13000

プロキシは /main/ を転送し、Host とプロトコルのヘッダー、Cookie、WebSocket を適切に扱う必要があります。インストーラーは DNS や HTTPS を設定しません。

インストール結果を確認する

JSON の ok: true は成功、result.started: true は起動時のヘルスチェック成功、result.url はアプリの入口です。result.initialAdmin.username と設定したパスワードでサインインします。

サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta status \
  --dir /srv/nocobase/my-app --json

result.health.ok が true、result.process.status が online、result.node.matches が true、result.pending が null であることを確認します。サーバーでヘルスエンドポイントを確認します:

サーバー · 元のサービスアカウント、任意のディレクトリ
curl --fail http://127.0.0.1:13000/main/api/healthz

ok: true を確認したらブラウザーでサインインし、ページの再読み込みと権限を確認します。ドメインがあれば実際のドメインで確認してください。接続できない場合はサーバーで status を確認し、DNS、プロキシ、ネットワークを調べます。

自動起動と永続性を確認する

サーバー · 元のサービスアカウント、任意のディレクトリ
pm2 startup

表示されたシステム設定コマンドを実行し、プロセス一覧を保存します:

サーバー · 元のサービスアカウント、任意のディレクトリ
pm2 save

インストール先の主な構成は次のとおりです:

ディレクトリ構成
/srv/nocobase/my-app/
├── installer.json
├── app.env
├── config.yml
├── storage/
├── logs/
├── backups/
├── current -> releases/<release>/app
└── releases/

設定とデータはリリースの外に保存されます。業務レコードを作成し、対応していればファイルもアップロードしてから、サーバーで再起動します:

サーバー · 元のサービスアカウント、任意のディレクトリ
pm2 restart nocobase-my-app

再度サインインし、元のレコード、ファイル、権限が残り、定期実行ジョブが動くことを確認します。アプリの再起動とサーバー起動後の復旧は別の確認です。サーバーの再起動が可能な時間に自動復旧も確認してください。

新しいバージョンを手動でデプロイする

新しいアーカイブをビルドする

開発マシン · アプリのソースディレクトリ my-app/
pnpm build --target linux-x64 --node-version 24 --tar

ビルドは storage/exports/dist.tar.gz を上書きするため、必要な旧アーカイブは先に別の場所へ保存します。対象バージョンのマイグレーションと設定変更の説明を確認してください。

状態とデプロイ計画を確認する

まず開発マシンから新しいアーカイブをアップロードします:

開発マシン · アプリのソースディレクトリ my-app/
scp storage/exports/dist.tar.gz deploy@server:/tmp/my-app-new.tar.gz

次にサーバーで実行します:

サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta status \
  --dir /srv/nocobase/my-app --json
サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta upgrade \
  --dir /srv/nocobase/my-app \
  --archive /tmp/my-app-new.tar.gz --json

新しいバージョンはサーバー上の upgrade でデプロイします。--origin、--host、--port、--name、--set などの初回用引数は省略し、元の設定を使います。

更新が必要な場合は、事前確認が CONFIRMATION_REQUIRED を返し、停止、バックアップ、マイグレーションへの影響を示します。この時点では切り替えておらず、旧バージョンが稼働しています。同じアーカイブの再実行は success-noop になり、同じアプリバージョンでも再ビルドしたアーカイブは別のリリースになれます。

バックアップ範囲を確認する

アプリを停止した後、インストーラーは設定から特定できる SQLite データベース、config.yml、app.env をバックアップします。アップロードファイル、外部データベース、オブジェクトストレージは別途バックアップしてください。--backup-done は外部データベースのバックアップ完了を宣言するだけで、バックアップや復元は実行しません。

このバージョンは設定、実行予定のマイグレーション、過去のマイグレーションとシードのチェックサムを確認します。CHECKSUM_REPAIR_REQUIRED が返されたら、各変更をバージョンの説明と照合してください。通常の --yes は修復を許可しません。確認後に限り、同じコマンドに返された計画の --repair-checksums <token> を追加します。ツールはバックアップ後に承認済みの修復とマイグレーションを実行します。事前確認を回避するために先に手動修復しないでください。

確認してデプロイする

計画、バックアップ、停止時間を確認したら、サーバーで実行します:

サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta upgrade \
  --dir /srv/nocobase/my-app \
  --archive /tmp/my-app-new.tar.gz --yes --json

インストーラーはアプリを停止し、バックアップ、マイグレーション、リリース切り替え、起動確認を行います。設定、シークレット、データは保持します。install や config init は再実行しません。

先頭の npx --yes はインストーラーの取得確認だけです。コマンド末尾の --yes が今回の更新を許可します。外部データベースは先にバックアップし、選択したコマンドに --backup-done を追加してください。

新しいバージョンを確認する

同じ対象で status を再実行し、新しいリリースと正常性を確認してから元の URL でサインインします。既存レコード、アップロード、ユーザー権限、新機能、バックグラウンドジョブを確認してください。

ソースのバージョンとアーカイブのチェックサムを記録し、旧アーカイブとバックアップを保持します。リリースの保存数は既定で 3 つで、--keep で変更できます。削除されたリリースには直接ロールバックできません。

デプロイ失敗とロールバック

エラーとログを残し、同じ対象の status で稼働中リリースと pending を確認します。すでに旧版へ自動復旧している場合があります。終了コード 3 は更新失敗後にロールバック済み、4 はロールバックも失敗して停止中です。再初期化せず、JSON のエラーと復旧案内を確認してください。

サーバーでロールバック計画を確認します:

サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta rollback \
  --dir /srv/nocobase/my-app --json

データへの影響を確認して実行します:

サーバー · 元のサービスアカウント、任意のディレクトリ
npx --yes @nocobase/app-installer@beta rollback \
  --dir /srv/nocobase/my-app --yes --json

まず末尾に --yes がないコマンドを実行し、確認してから 2 つ目を実行します。マイグレーションやチェックサム修復を行った更新では、ロールバックで元の SQLite バックアップを復元し、その後の業務データの書き込みが失われる場合があります。外部データベースとアップロードは個別の復元が必要です。--no-restore は旧版と現在のデータベースの互換性が確認できた場合だけ検討してください。

処理が中断した場合は、サーバーで status を実行し、プロセスと pending を確認します。すぐに再デプロイせず、状態を確かめて返された復旧手順に従ってください。

日常の管理

サーバー · 元のサービスアカウント、任意のディレクトリ
# Process status
pm2 status nocobase-my-app

# Logs; press Ctrl+C to stop following
pm2 logs nocobase-my-app --lines 100

# Restart
pm2 restart nocobase-my-app

# Stop
pm2 stop nocobase-my-app

# Resume
pm2 restart nocobase-my-app

公開 origin、待ち受けアドレス、ポートを変える場合は、インストール先の app.env を編集します。ポートが空いていることを確認し、必要に応じてプロキシを変更してから再起動し、status と実際の URL を確認してください。current を上書きしたり、インストール済みリリース内のビルドファイルを編集したりしないでください。

よくある問題

現象次の確認
PORT_IN_USEアプリ用の空きポートを選び origin も更新します。無関係なプロセスは停止しません。
DRIVER_MISSINGアプリのソースに対象データベースのドライバーを追加し、アーカイブを再ビルドします。
START_FAILED返されたログのパスとインストール先の logs/ で設定、データベース、起動エラーを確認します。
状態は正常だがアクセスできない待ち受けアドレス、ポート、ファイアウォール、DNS、プロキシを確認し、アプリのパスを含む URL を使います。

調査には JSON の error.code、error.message、error.suggestions を保持し、シークレットを含む設定ファイルは出力しないでください。

NocoBase ドキュメントアシスタント

NocoBase について何を知りたいですか?

質問は個別に回答され、過去の質問や回答は参照されません。必要な背景をすべて含めてください。