---
pkg: "@nocobase/preset-cluster"
title: "クラスター展開の準備"
description: "クラスター展開前の準備：商用プラグインライセンス（PubSub、Queue、Lock、Worker ID アダプター）、データベース、Redis／RabbitMQ ミドルウェア、共有ストレージ、負荷分散。"
keywords: "クラスター準備,商用ライセンス,Redis,RabbitMQ,共有ストレージ,負荷分散,Nginx,NocoBase"
---

# 準備作業

クラスターアプリケーションをデプロイする前に、以下の準備作業を完了する必要があります。

## 商用プラグインライセンス

NocoBaseアプリケーションをクラスターモードで実行するには、以下の**プラグイン**のサポートが必要です。

| 機能                 | プラグイン                                                                              |
| -------------------- | ----------------------------------------------------------------------------------- |
| キャッシュアダプター | ビルトイン                                                                            |
| 同期シグナルアダプター | `@nocobase/plugin-pubsub-adapter-redis`                                             |
| メッセージキューアダプター | `@nocobase/plugin-queue-adapter-redis` または `@nocobase/plugin-queue-adapter-rabbitmq` |
| 分散ロックアダプター | `@nocobase/plugin-lock-adapter-redis`                                               |
| Worker ID アロケーター | `@nocobase/plugin-workerid-allocator-redis`                                         |

まず、上記の**プラグイン**のライセンスを取得していることを確認してください（対応する**プラグイン**ライセンスは、商用**プラグイン**サービスプラットフォームから購入できます）。

## システムコンポーネント

アプリケーションインスタンス自体に加えて、クラスター配備にはデータベース、ミドルウェア、共有ストレージ、ロードバランシングなどのシステムコンポーネントも必要です。これらのコンポーネントの具体的な実装は、各チームが自社の運用体制に応じて選択できます。

### データベース

現在のクラスターモードはアプリケーションインスタンスのみを対象としているため、データベースは一時的にシングルノードのみをサポートしています。もしマスター・スレーブなどのデータベースアーキテクチャをお持ちの場合は、ミドルウェアを介してご自身で実装し、NocoBaseアプリケーションに対して透過的であることを保証する必要があります。

可用性ゾーンやリージョンをまたぐウォームスタンバイや災害復旧が必要な場合、データベースの同期および切り替え戦略は運用チーム自身が設計・実装する必要があります。

### ミドルウェア

NocoBaseのクラスターモードは、クラスター間の通信と連携を実現するために、いくつかのミドルウェアに依存しています。これには以下が含まれます。

-   **キャッシュ**：Redisベースの分散キャッシュミドルウェアを使用し、データアクセス速度を向上させます。
-   **同期シグナル**：RedisのStream機能を利用して、クラスター間の同期シグナル伝達を実現します。
-   **メッセージキュー**：RedisまたはRabbitMQベースのメッセージキューミドルウェアを使用し、非同期メッセージ処理を実現します。
-   **分散ロック**：Redisベースの分散ロックを使用し、クラスター内の共有リソースへの安全なアクセスを保証します。

すべてのミドルウェアでRedisを使用する場合、クラスターの内部ネットワーク（またはKubernetes）内で単一のRedisサービスを起動できます。また、機能ごと（キャッシュ、同期シグナル、メッセージキュー、分散ロック）に個別のRedisサービスを有効にすることも可能です。

**推奨バージョン**

-   Redis：8.0以上、またはBloom Filter機能を含むredis-stackバージョン。
-   RabbitMQ：4.0以上。

### 共有ストレージ

NocoBaseは、システム関連ファイルを保存するために`storage`ディレクトリを使用します。また、共有ストレージはクラスター配備における必須コンポーネントでもあります。マルチノードモードでは、複数ノード間の共有アクセスを実現するために、インフラ環境に応じてクラウドディスク、NFS、EFSなどの実装を選択できます。そうしないと、システムファイルは自動的に同期されず、アプリケーションは正常に動作しません。

Kubernetesでデプロイする場合は、[Kubernetesデプロイ：共有ストレージ](./kubernetes#共有ストレージ)の章を参照してください。

#### `storage` ディレクトリには通常何が保存されるか

`storage` ディレクトリの内容は、有効化されているプラグインやデプロイ方式によって異なります。現在の実装に基づく代表的な内容は以下のとおりです。

| パス | 用途 | 利用上の推奨 |
| --- | --- | --- |
| `storage/uploads` | ローカルストレージモードでアップロードされたファイル | 本番クラスターでは S3 / OSS / COS などのオブジェクトストレージを優先してください |
| `storage/plugins` | 実行時にインストール、アップロード、または検出されるローカルプラグインパッケージ | ローカルプラグインに依存する場合は共有が必須です。プラグインがイメージに組み込まれていれば、この依存は減らせます |
| `storage/apps/<app>/jwt_secret.dat` | `APP_KEY` が明示設定されていない場合に自動生成されるデフォルトのトークン秘密鍵 | 本番環境ではこのファイルに依存せず、`APP_KEY` を明示的に設定してください |
| `storage/apps/<app>/aes_key.dat` | `APP_AES_SECRET_KEY` が明示設定されていない場合に自動生成されるデフォルトの AES 鍵 | 本番環境ではこのファイルに依存せず、`APP_AES_SECRET_KEY` を明示的に設定してください |
| `storage/environment-variables/<app>/aes_key.dat` | 環境変数プラグイン利用時の AES 鍵ファイル | 読み取り専用でマウントした鍵ファイルの利用を推奨します |
| `storage/logs` | デフォルトのログディレクトリおよび一部のマイグレーションログ | 将来的には外部ログ基盤への連携を推奨します |
| `storage/tmp` | インポート、エクスポート、マイグレーションなどの一時ファイル | 一時ディレクトリでも構いませんが、ノード間で再利用が必要な場合は共有するか、単一の管理ノードに固定して実行してください |
| `storage/backups`、`storage/duplicator`、`storage/migration-manager` | バックアップ、リストア、マイグレーション関連の成果物 | 運用用ディレクトリとして扱い、永続保存し、複数ノードから同時変更しないようにしてください |

上記の表は網羅的ではありませんが、重要な点を示しています。`storage` には業務ファイル、鍵ファイル、プラグインディレクトリ、ログ、運用系の一時成果物が混在します。そのため、クラスター配備では通常、`/app/nocobase/storage` 全体を共有かつ永続化することが基本方針になります。

#### ストレージに関する推奨事項

NocoBase におけるクラスター整合性は、主にデータベース、Redis、メッセージキュー、分散ロックによって担保されており、共有ファイルシステムを高並行な調整媒体として使う前提ではありません。

そのため、以下を推奨します。

- 添付ファイルのような高頻度な業務ファイルは、オブジェクトストレージを優先してください。本番クラスターでローカルストレージに長期依存することは推奨されません。
- 共有ストレージは主に `storage` ディレクトリを保持するために使用し、高スループットなファイルストレージサービスとしては扱わないでください。
- プラグインのインストール、プラグインのアップグレード、バックアップ、リストア、マイグレーションなどの操作は、クラスターを単一ノードまで縮退させてから実施し、完了後に再度スケールアウトしてください。

### ロードバランシング

クラスターモードでは、リクエストの分散、アプリケーションインスタンスのヘルスチェック、およびフェイルオーバーを実現するために、ロードバランサーが必要です。この部分は、チームの運用要件に応じてご自身で選択・設定してください。

セルフホスト型Nginxを例にとると、設定ファイルに以下の内容を追加します。

```
upstream myapp {
    server 172.31.0.1:13000; # 内部ノード1
    server 172.31.0.2:13000; # 内部ノード2
    server 172.31.0.3:13000; # 内部ノード3
}

server {
    listen 80;

    location / {
        # 定義されたupstreamを使用してロードバランシングを行います
        proxy_pass http://myapp;
        # ... その他の設定
    }
}
```

これは、リクエストをリバースプロキシし、異なるサーバーノードに分散して処理することを意味します。

他のクラウドサービスプロバイダーが提供するロードバランシングミドルウェアについては、各プロバイダーが提供する設定ドキュメントを参照してください。

高可用性を前提とした配備では、以下を推奨します。

- 同一クラスター内で少なくとも 2 つのアプリケーションインスタンスを稼働させ、インスタンス障害時のフェイルオーバーはロードバランサーに任せてください。
- ロードバランサーのヘルスチェックは、単にポートが開いているかではなく、アプリケーションの実際の可用性を反映するようにしてください。
- 可用性ゾーンやリージョンをまたぐウォームスタンバイが必要な場合は、通常は複数の独立したクラスターを配備し、データベース、共有ストレージ、その他インフラの同期と切り替えは運用チームが担当します。

## 環境変数設定

クラスター内のすべてのノードは、同じ環境変数設定を使用する必要があります。NocoBaseの基本的な[環境変数](../api/app/env)に加えて、以下のミドルウェア関連の環境変数も設定する必要があります。

### 重要な鍵

ミドルウェア関連の環境変数に加えて、クラスター内のすべてのノードでは、以下の重要な鍵も同一の値で明示的に設定する必要があります。

```ini
APP_KEY=
APP_AES_SECRET_KEY=
# または読み取り専用でマウントした鍵ファイルを使用
# APP_AES_SECRET_KEY_PATH=
```

- `APP_KEY` は token / JWT の署名に使用されます。明示設定しない場合、アプリケーションは `storage` 配下のデフォルト鍵ファイルにフォールバックします。
- `APP_AES_SECRET_KEY` はデータベース内の機微なフィールドの復号に使用されます。明示設定しない場合、こちらも `storage` 配下のデフォルト鍵ファイルにフォールバックします。
- 一時的なコンテナ環境やマルチノード配備で自動生成されたローカル鍵ファイルに依存すると、再起動後にトークンが無効化されたり、過去の暗号化データが復号できなくなったりする可能性があります。

:::info{title=ヒント}
`APP_AES_SECRET_KEY` は 32 バイトの AES-256 鍵であり、64 文字の 16 進文字列で表現する必要があります。

クラウド環境では、Secrets Manager、SSM Parameter Store、Kubernetes Secret、または読み取り専用でマウントした鍵ファイルなどを使って、これらの値を一元管理することを推奨します。
:::

### マルチコアモード

アプリケーションがマルチコアノードで実行される場合、ノードのマルチコアモードを有効にできます。

```ini
# PM2マルチコアモードを有効にする
# CLUSTER_MODE=max # デフォルトでは無効になっています。手動で設定する必要があります。
```

KubernetesでアプリケーションPodをデプロイする場合は、この設定を無視し、Podのレプリカ数によってアプリケーションインスタンスの数を制御できます。

### キャッシュ

```ini
# キャッシュアダプター。クラスターモードではredisと設定する必要があります（未設定の場合、デフォルトはインメモリです）。
CACHE_DEFAULT_STORE=redis

# Redisキャッシュアダプターの接続URL。必ず入力してください。
CACHE_REDIS_URL=
```

### 同期シグナル

```ini
# Redis同期アダプターの接続URL。未設定の場合、デフォルトはredis://localhost:6379/0です。
PUBSUB_ADAPTER_REDIS_URL=
```

### 分散ロック

```ini
# ロックアダプター。クラスターモードではredisと設定する必要があります（未設定の場合、デフォルトはインメモリローカルロックです）。
LOCK_ADAPTER_DEFAULT=redis

# Redisロックアダプターの接続URL。未設定の場合、デフォルトはredis://localhost:6379/0です。
LOCK_ADAPTER_REDIS_URL=
```

### メッセージキュー

```ini
# Redisをメッセージキューアダプターとして有効にします（未設定の場合、デフォルトはインメモリアダプターです）。
QUEUE_ADAPTER=redis
# Redisメッセージキューアダプターの接続URL。未設定の場合、デフォルトはredis://localhost:6379/0です。
QUEUE_ADAPTER_REDIS_URL=
```

### Worker ID アロケーター

NocoBaseの一部のシステム**コレクション**では、主キーとしてグローバルユニークIDを使用しています。このため、クラスター全体で主キーの競合を防ぐために、Worker IDアロケーターを介して各アプリケーションインスタンスに一意のWorker IDが割り当てられるようにする必要があります。現在のWorker IDの範囲は0〜31であり、これは同じアプリケーションが最大32ノードで同時に実行できることを意味します。グローバルユニークIDの設計については、[@nocobase/snowflake-id](https://github.com/nocobase/nocobase/tree/main/packages/core/snowflake-id)を参照してください。

```ini
# Worker IDアロケーターのRedis接続URL。省略した場合、Worker IDはランダムに割り当てられます。
REDIS_URL=
```

:::info{title=ヒント}
通常、関連するアダプターはすべて同じRedisインスタンスを使用できますが、キーの競合の可能性を避けるため、異なるデータベースを使い分けることをお勧めします。例えば、以下のようになります。

```ini
CACHE_REDIS_URL=redis://localhost:6379/0
PUBSUB_ADAPTER_REDIS_URL=redis://localhost:6379/1
LOCK_ADAPTER_REDIS_URL=redis://localhost:6379/2
QUEUE_ADAPTER_REDIS_URL=redis://localhost:6379/3
REDIS_URL=redis://localhost:6379/4
```

現時点では、各**プラグイン**はそれぞれ独自のRedis関連環境変数を使用しています。将来的には、`REDIS_URL`をフォールバック設定として統一的に使用することを検討する可能性があります。

:::

Kubernetesを使用してクラスターを管理する場合、上記の環境変数をConfigMapまたはSecretに設定できます。詳細については、[Kubernetesデプロイ](./kubernetes)を参照してください。

上記のすべての準備作業が完了したら、[運用プロセス](./operations)に進み、アプリケーションインスタンスの管理を続行できます。
