セルフホスティング (自前の runner プロジェクト)
自前の runner プロジェクトで api イメージを作り、web フロントエンドまで結線して本番デプロイする手順
このページは、公式の full / slim イメージでは要件を満たせない場合に、自前の runner プロジェクトを作って本番デプロイする運用者向けの手順です。具体的には 次のようなケースを想定しています。
- 公式イメージに同梱されない独自プラグイン(社内 npm レジストリのものなど)を 読み込みたい
- ストレージ / 検索 / メール / レンダラのドライバを任意の組み合わせで固定したい
- イメージの依存を必要最小限に絞り、ビルドパイプラインを自社で管理したい
公開されている full / slim イメージで足りる場合は、公式イメージで動かす だけで十分です。ここではその一歩先、runner プロジェクトを一から作る場合を 扱います。
Crowi の本番構成は「api(Hono)+ web(Next.js)+ MongoDB(+ 任意で Redis /
Elasticsearch / S3)」です。@crowi/api はプラグインを同梱しないため、
どのドライバを使うかは runner プロジェクトが所有します。この前提は
設定 の「プラグインの解決方法」で詳しく説明しています。
全体像
web と api は別コンテナで、いずれもコンテナ内ポート 3000 で待ち受けます。ブラウザにはその前段に置いた
リバースプロキシの 1 オリジンだけを見せ、/api・/files とリアルタイムの WebSocket を api へ振り分けます。
プロキシの設定例 (Caddy / nginx)、WebSocket の Upgrade 透過、アップロードの body size 上限は
デプロイ構成 にまとめてあります。本番投入前に必ず読んでください。
runner プロジェクトを作る
プロジェクトディレクトリと package.json
任意の場所にディレクトリを作り、@crowi/api と使いたいプラグインを依存に
宣言します。下記は S3 ストレージ + Elasticsearch 検索 + PlantUML/KaTeX
レンダラを使う例です。
{
"name": "my-crowi-runner",
"private": true,
"type": "module",
"scripts": {
"start": "crowi-api"
},
"dependencies": {
"@crowi/api": "2.0.0-alpha.17",
"@crowi/plugin-storage-aws-s3": "2.0.0-alpha.17",
"@crowi/plugin-search-elasticsearch": "2.0.0-alpha.17",
"@crowi/plugin-renderer-plantuml": "2.0.0-alpha.17",
"@crowi/plugin-renderer-katex": "2.0.0-alpha.17"
}
}バージョンは実際に使う Crowi のリリースに揃えてください。@crowi/api と
@crowi/plugin-* は同一バージョンで足並みを揃えるのが安全です(リリースは
linked group として同時にバージョンが上がります)。
暗黙のデフォルトプラグイン(@crowi/plugin-storage-local /
@crowi/plugin-search-mongo / @crowi/plugin-mail-smtp)は宣言しなくても
読み込まれます。ローカルストレージ + MongoDB 検索 + SMTP のままでよければ、
@crowi/api だけを依存にすれば動きます。slim 相当を自前で組む形です。
crowi.config.json
読み込むプラグインと有効ドライバを宣言します。プラグインごとの設定値(バケット名
や認証情報など)はここには書かず、起動後に管理画面(/admin/plugins)から
設定します。
{
"plugins": [
"@crowi/plugin-storage-aws-s3",
"@crowi/plugin-search-elasticsearch",
"@crowi/plugin-renderer-plantuml",
"@crowi/plugin-renderer-katex"
],
"storage": { "driver": "s3" },
"search": { "driver": "elasticsearch" }
}フィールドの意味とドライバ名の対応は crowi.config.json を参照してください。
.env
api が起動時に読む環境変数を用意します。MONGO_URI と SECRET_TOKEN は
必須です(SECRET_TOKEN が未設定・空・空白のみ・既知の placeholder の
場合、api は起動しません)。本番では CROWI_ENCRYPTION_KEY も必ず設定
してください。
MONGO_URI=mongodb://mongodb:27017/crowi
REDIS_URL=redis://redis:6379 # 複数レプリカ運用では必須
CROWI_ENCRYPTION_KEY=... # openssl rand -base64 32
SECRET_TOKEN=... # openssl rand -base64 32、全レプリカで同じ値各変数の意味は 環境変数 を参照してください。
ローカルで起動確認
依存をインストールし、runner プロジェクトのディレクトリを作業ディレクトリにして 起動します。
pnpm install # または npm install
pnpm start # = crowi-api。api がコンテナ内ポート 3000 で待ち受けるapi は起動時にこのプロジェクトの node_modules/ からプラグインを解決します。
プラグインを追加・削除しても api の再ビルドは不要です。
api の Docker イメージを作る
runner プロジェクトをそのままイメージ化します。公式イメージと同じく、
WORKDIR を runner プロジェクトのルートにし、
node_modules/@crowi/api/dist/app.js を実行します。
FROM node:24-bookworm-slim
WORKDIR /app
# runner プロジェクトのマニフェストを先に入れて依存だけ先に解決(キャッシュ効率)
COPY package.json pnpm-lock.yaml* package-lock.json* ./
RUN corepack enable && pnpm install --prod || npm install --omit=dev
# 設定とソースを配置
COPY crowi.config.json ./
# .env はイメージに焼き込まず、コンテナ env / env_file で渡すことを推奨
ENV NODE_ENV=production
ENV PORT=3000
EXPOSE 3000
CMD ["node", "node_modules/@crowi/api/dist/app.js"]社内レジストリのプラグインを使う場合は、pnpm install の前に .npmrc を
COPY してレジストリ / 認証を設定してください。crowi.config.json を
コンテナ外からマウントすれば、再ビルドなしでドライバ選択を差し替えられます
(公式 compose もこの方式です)。
機密値(CROWI_ENCRYPTION_KEY / SECRET_TOKEN など)はイメージに
焼き込まず、デプロイ時のコンテナ環境変数か env_file で渡します。
web フロントエンドを結線する
web は公開されている crowi/crowi-web イメージをそのまま使います。これは描画専任の
Next サーバで、絶対 API URL を一切焼き込みません。ブラウザは自分のオリジンの相対パス /api・/files を叩き、
WebSocket URL は window.location から導出します。そのため 1 つのイメージがどの
api を宛先にしても動きますが、それらのパスを api へ振り分ける前段のリバースプロキシが必要です。
web サーバを直接公開して /api の proxy を任せないでください。web に内蔵の
proxy は宛先をビルド時に焼き込む (CROWI_API_URL を実行時に読まない) ため、
直接公開した web サーバはビルド時の既定の宛先に proxy してしまい、api に届きません。
前段にリバースプロキシを置いてください。
推奨構成は web と api の前段に同一オリジン + リバースプロキシを置く形です。
プロキシの振り分け(/api・/files、およびリアルタイムの /collab・/presence・
/notifications の WebSocket アップグレード)の Caddy / nginx 最小例と、
クロスオリジン・Vercel / PaaS の各バリエーションは
デプロイ構成 にまとめてあります。本番投入前に必ず読んでください。
起動順とヘルスチェック
ミドルウェアを先に起動
MongoDB(必要に応じて Redis / Elasticsearch)を起動し、到達可能にします。
マイグレーションを適用
v1 からのアップグレードや preflight マイグレーションがある場合は、api 起動前に 適用します。詳細は v1 からの移行 を参照してください。
api → web の順で起動
api を起動して /api/app/info が 200 を返すことを確認してから、web を起動します。
複数レプリカで運用する場合は、REDIS_URL と CROWI_MULTI_INSTANCE の
扱いが変わります。SECRET_TOKEN は単一・複数レプリカのどちらでも必須
ですが、複数レプリカでは 全レプリカを完全に同じ値 にする必要が
あります。値を変更する(ローテーションする)場合は、旧レプリカを
drain・停止してから新しい値の新版レプリカを起動する
drain-first の手順を踏んでください。新旧レプリカが異なる値で同時に
稼働する期間を作ってはいけません。環境変数 と
リアルタイム共同編集の運用 を参照してください。
次のステップ
- デプロイ構成 — リバースプロキシと公開オリジン
- 設定 — 設定レイヤーとプラグインの解決方法
- 環境変数 — 変数名・既定値・意味の一覧
- crowi.config.json — フィールドとドライバ名の一覧
- 機密設定の暗号化 —
CROWI_ENCRYPTION_KEYのセットアップ - ストレージ設定 —
storage.driverの切り替え - 検索バックエンドのセットアップ — Elasticsearch の設定
- プラグインの導入と設定 — プラグインの追加・有効化
- バージョンアップ — 版ごとの入れ替え手順
- v1 からの移行 — 既存 Crowi からの移行