Crowi

設定

環境変数と crowi.config.json による Crowi の設定

Crowi 2.0 の設定は、大きく 3 つのレイヤーに分かれています。

  1. 環境変数 (.env / プロセス環境) — 接続先や暗号鍵など、起動時に 必要な値。
  2. crowi.config.json — どのプラグインを読み込み、どのドライバを 有効にするか。
  3. 管理画面の設定 — アプリのタイトルや OAuth、メール、ストレージの 詳細値。MongoDB の Config コレクションに保存されます。

このページでは 1 と 2 を扱います。3 の設定値については 管理画面 を参照してください。

環境変数

API は起動時に、起動した作業ディレクトリの .env を読み込みます。 開発時のそのディレクトリは リポジトリルート です (pnpm dev の api スクリプトが明示的に読み込みます)。本番では runner プロジェクトのディレクトリ になるか、もしくはファイルの代わりに compose / オーケストレータから変数を注入します。.env.example をコピーして 編集してください。

cp .env.example .env

API は、起動時に検証できる値を起動時にまとめて検証します。一方、値によっては起動時ではなく実際に使われる時点で解釈されるものもあります(LOG_LEVEL がそれで、不正な値は起動時の一括検証ではなく最初にログを出力しようとした時点で報告されます)。PORT / MONGO_URI (またはエイリアス) / REDIS_URL (またはエイリアス) / CROWI_ENCRYPTION_KEY / CROWI_ARTIFACT_ORIGIN の形式が不正な場合、検出できた問題をすべて含む 1 つのエラーメッセージとともに起動が即座に失敗します。CLIENT_URL / CROWI_MULTI_INSTANCE / NODE_ENV / JWT_ACCESS_TOKEN_TTL_SECONDS / JWT_REFRESH_TOKEN_TTL_SECONDS / COLLAB_MAX_EDITORS_PER_PAGE / MIGRATION_PREFLIGHT_UNAPPLIED_POLICY などの形式不正は起動を妨げず、起動ログの 1 箇所にまとめて warning として 出力されます(CLIENT_URL が未設定の場合も、送信メール内のリンクが相対 パスになってしまう旨の warning が同じレポートに含まれます)。

SECRET_TOKEN は必須です。未設定・空文字・空白のみ・既知の placeholder 値のいずれかであれば、NODE_ENV や CROWI_MULTI_INSTANCE の 値に関係なく起動が失敗します。加えて、NODE_ENV の値によって重大度が 変わる例外でもあります。32 文字未満の値は NODE_ENV=production (未設定時も含む) では起動失敗、それ以外の環境では警告に留まります。 旧 WS_TOKEN_SECRET は非推奨の legacy alias として引き続き読みます。 要件は 環境変数 の該当行を参照してください。

CROWI_ / WS_TOKEN_ / JWT_ / COLLAB_ / REDIS / MONGO / MIGRATION_ のいずれかの既知プレフィックスを持つものの、既知の変数名の どれとも完全一致しない環境変数は、タイポの疑いとして同じ warning レポートに含まれます。判定にはレーベンシュタイン距離(編集距離)を使い、 既知の変数名のうち最も近いものとの距離が 2 以下であれば「もしかして XXX では?」という形で warning を出します(fail にはなりません。誤検知 を許容するヒューリスティックです)。PATH / CI / GITHUB_* / npm_* など上記プレフィックスを持たない一般的な OS/CI 環境変数は対象外です。

api の構造化ロガーを経由するレコードは、標準出力・標準エラー出力ともに 1 行 1 レコードの NDJSON です。HTTP リクエストの処理中に出力されたレコードは、そのリクエストとの相関に使う request id を持ちます。プリティプリント・収集・保管は運用者側の責務です (LOG_LEVEL の詳細は 環境変数 を参照)。起動時の進捗表示 (boot reporter)、@@crowi:fail マーカー、構造化ロガーを経由しない console.* 呼び出しはこの対象外でプレーンテキストのまま出力されるため、api のプロセス全出力をそのまま厳密な NDJSON パーサへ渡せるとは限りません。

変数の一覧

変数名・既定値・意味の一覧は 環境変数 にあります。共同編集で使う変数の使い分けは リアルタイム共同編集の運用、構成ごとの NEXT_PUBLIC_API_URL / NEXT_PUBLIC_COLLAB_URL の選び方は デプロイ構成 を参照してください。

Tip: SECRET_TOKEN と CROWI_ENCRYPTION_KEY はどちらも openssl rand -base64 32 で生成できます。CROWI_ENCRYPTION_KEY は pnpm --filter @crowi/api crypto:gen-key でも生成できます。

MCP エンドポイント

AI クライアント向けの MCP エンドポイント /api/mcp は常に有効で、フィーチャーフラグはありません。運用者が気にする点は 3 つです。

  • 認証は個人アクセストークンのみです。 web のセッションや OAuth アクセストークンでは接続できません。利用者側の手順は AI ツールから使う (MCP) を参照してください。
  • 前段のプロキシは /api/* を api へ転送するだけで足ります。 MCP クライアントは wiki と同じ origin の /api/mcp に接続します。追加で公開するポートやプロセスはありません。
  • REDIS_URL を設定するとレート制限の予算がレプリカ間で共有されます。 未設定の場合は各レプリカがメモリ内で予算を持つため、レプリカ数だけ実効の上限が上がります。

サーバーはステートレス (リクエストごとに新しいセッション) なので、複数レプリカ構成でも sticky session は不要です。

Docker での環境変数

docker compose --profile app で全スタックを起動する場合、api サービスは .env を env_file として読み込みます。ただし コンテナネットワーク向けの URI (MONGO_URI / REDIS_URL / CLIENT_URL) は docker-compose.yml 側の environment 指定が .env の値を上書きします。機密値 (CROWI_ENCRYPTION_KEY / SECRET_TOKEN など) は .env に書いておけばそのまま渡ります。

Tip: Web アプリ (@crowi/web) はプラグイン依存ゼロの 独立した デプロイ対象 です。api とは HTTP で通信し、どこにでもデプロイできます (Vercel・コンテナ・api と同居など)。一方 api は長寿命の Node サーバ (データベースへの持続的な接続・レプリカ間の pub/sub・常駐する WebSocket サーバ・起動時のプラグイン読み込み) であり、Node ランタイムが必須 です。Node ホストまたは Node コンテナ (ECS / EKS / Fly / Render / Cloud Run / Cloudflare Containers) で動作します。Cloudflare Workers のような edge/isolate 系のサーバレス基盤では動作しません。

レンダラ plugin アセットと CSP (Content-Security-Policy)

KaTeX のような一部のレンダラ plugin は、CSS / font などの静的アセットを 自身の public route (/api/plugins/<plugin-name>/...) から配信します。 Web はどのレンダラ plugin が有効かを api に問い合わせ、そのスタイルシートを api origin に対する <link rel="stylesheet"> として読み込みます。 plugin 名や CSS の存在を Web 側が事前に知る必要はありません。

Web と api が 同一オリジン (推奨のリバースプロキシ構成、上記参照) の deployment では追加の設定は不要です。既存の CORS policy (CLIENT_URL を 許可オリジンとする) は CSS / font のクロスオリジンレスポンスにも そのまま適用されるため、CORS 側の追加設定も不要です。

Web と api を 別オリジン で運用し、かつ operator が Content-Security-Policy を付与している deployment では、style-src と font-src に api の origin を許可してください。例えば CLIENT_URL=https://wiki.example.com、api が https://api.example.com で動く構成では、Web が返す CSP ヘッダにおおよそ次のように追加します。

Content-Security-Policy: style-src 'self' https://api.example.com; font-src 'self' https://api.example.com; ...

許可を追加し忘れると、対象の plugin が有効でも CSS / font がブラウザに ブロックされ、スタイルが当たらない状態になります (plugin 自体は正常に 動作しているため、api / Web のログにはエラーが出ません。ブラウザの コンソールで CSP violation を確認してください)。

HTML artifact の配信 (CROWI_ARTIFACT_ORIGIN)

HTML artifact ページは、Crowi に到達できる security context では絶対に 実行されてはいけません。配信モードは 2 つあり、どちらも既定では無効です。

  • separate-origin (推奨): CROWI_ARTIFACT_ORIGIN に CLIENT_URL と 異なる hostname を設定します。同じ hostname の別 port / scheme は boot 時に拒否されます。cookie は origin ではなく host 単位でスコープ されるためです。可能であれば別の registrable domain を用意してください (例: wiki.example.com に対して artifacts.example.net)。その origin は同じ api process へ到達できる必要があります(reverse proxy の設定、 またはその api を指す別の DNS レコードを使います。api 自身はこれを検証できない ため、下記の smoke check で確認します)。
  • same-origin (明示的な opt-in): 環境変数ではなく Admin > Artifact から有効化します。CLIENT_URL の設定が必須で、api がその同一 origin 配下(推奨のリバースプロキシ構成)で到達できることを前提とします。api を 別ホストで公開している場合は separate-origin 配信を使ってください。 複数 api instance 構成では、この設定の他 instance への伝播は best-effort です。無効化した後は、全 instance に確実に反映させるため それぞれを再起動してください。

same-origin 配信の /_artifact-frame は、request の Host header から artifact の期待 host を導出します。手前に reverse proxy を置く場合は、元の Host header をそのまま転送するよう設定してください(Caddy は既定でそのまま転送します。nginx では proxy_set_header Host $host; が必要です)。転送されないと、正当な same-origin artifact request が Invalid or missing src. として拒否されます。

どちらのモードも設定していない場合、Crowi は通常どおり起動し、boot log に 設定手順が表示されます。いずれかを有効にするまで artifact の書き込みは 拒否されます(既存の artifact ページの閲覧は、実行可能なプレビューを 除いて引き続き動作します)。

署名付き artifact URL は SECRET_TOKEN(上記で必須)から導出される鍵で 署名されます。専用の設定は不要です。

CROWI_ARTIFACT_ORIGIN を設定したら、その origin が実際にこの Crowi instance へ到達しているか確認してください。

curl -fsS https://artifacts.example.net/api/app/info

この instance の version を含む 200 が返れば、routing は正しく設定 されています(本ドキュメントの他の箇所でも使っている boot 確認と同じ smoke check です)。到達しない場合、artifact ページの保存自体は通常どおり 行われますが、routing を直すまで配信できません(データは失われません)。

artifact origin からこの api instance へ到達させる必要がある path prefix は /api/artifact/(sandbox 化された文書自体が fetch する、token 認証の配信 route)だけです。署名付き配信 URL を発行する /api/pages/ への呼び出しは、wiki 側の通常の API 接続を通ります。配信 response が cookie を発行することはありません。60 秒だけ有効な署名付き URL が唯一の認証情報で、cookie は一切持ちません。

artifact ページの HTML を添付ファイルとしてダウンロードする機能(GET /pages/{id}/artifact-download、通常のセッション/PAT 認証配下)は配信モードとは独立していて、上記のどちらのモードも設定していなくても動作します。設定が必要なのは sandbox 化されたインラインプレビューだけです。

署名付き配信 URL の token は query string(?t=…)に載って運ばれます。Crowi 自身の log にはこれを一切記録しませんが、artifact origin の手前に置く reverse proxy や CDN は既定で request URL 全体を access log に記録することがあります。/api/artifact/ については query string を記録しないよう設定してください。漏れた log の 1 行が(有効期限内は)そのまま有効な配信 URL として再生されてしまいます。

same-origin 配信には知っておくべき残余リスクがあります。artifact への request にも Crowi のセッション cookie が送られます(文書自体からは分かり ません)。また、reverse proxy や CDN が response header を除去・上書き すると、sandbox による保護が警告なく失われます。Admin > Artifact の画面にも この 2 点をトグルの直前に表示しています。

crowi.config.json

crowi.config.json は runner プロジェクトのルート に置く JSON ファイルです。どのプラグインを読み込み、どのドライバを有効にするか を 宣言します。プラグインごとの 設定値 (S3 のバケット名、OAuth クライアント ID、メール / ストレージの 認証情報など) はここには書かず、MongoDB の Config コレクションに保存し、 管理画面から編集します。

{
  "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 にあります。ファイルが存在しない場合や項目を省略した場合は既定値が使われます。スキーマに合わない内容があると、明示的なエラーで起動に失敗します。

プラグインの解決方法

@crowi/api は プラグインを同梱しません。SDK (@crowi/plugin-api) と コアのみを出荷し、ドライバは同梱しません。プラグインは runner プロジェクトが 所有します。plugins に挙げた名前は、起動時に runner プロジェクト自身の node_modules/ から解決されます。 プラグインを追加するには、runner プロジェクトの package.json に依存として宣言した うえで crowi.config.json:plugins に名前を追加します。api パッケージ自体を 再ビルドする必要はありません。

@crowi/plugin-storage-local、@crowi/plugin-search-mongo、 @crowi/plugin-mail-smtp の 3 つは 暗黙のデフォルトプラグイン として 常に読み込まれ、設定不要で動作します。そのため、新規 インストールでは ローカルストレージ + MongoDB 検索 + SMTP メール が そのまま動きます。必須のインフラは MongoDB だけです。

runner プロジェクトは package.json の "start": "crowi-api" スクリプト (@crowi/api が提供する crowi-api bin) で起動します。プラグインを そのプロジェクトの node_modules/ から解決させるため、プロジェクト ディレクトリ自身から実行します。

プラグインが他のプラグインを requires で宣言している場合、その依存先も 自動で (transitive に) 解決・ロード されます。そのため、依存先を plugins に重ねて書く必要はありません。例えば @crowi/plugin-storage-aws-s3 と @crowi/plugin-mail-aws-ses は共通基盤の @crowi/plugin-aws を requires で宣言しているので、plugins には driver プラグインだけ を列挙すれば @crowi/plugin-aws は自動でロードされます。umbrella の @crowi/plugin-aws を明示列挙する必要はありません (重複ロードを避けるため)。AWS 一式を使う通し 手順は AWS Lightsail で動かす を参照してください。

プラグインの追加・有効化の詳しい手順は プラグインの導入と設定、 プラグインの種類は プラグインアーキテクチャ を参照して ください。

ドライバを選ばないプラグイン

レンダラ系プラグイン (@crowi/plugin-renderer-katex / -plantuml / -mermaid / -crowi-legacy) は plugins に追加するだけで有効になり、 storage / search のようなドライバ選択は不要です。絵文字ショートコードと リンクカード (@[card](url)) はプラグインではなく Crowi コアの機能で、 plugins への追加なしに常時有効です(リンクカードの外部取得は管理画面 「セキュリティ」の linkCardEnabled トグルで無効化できます)。

Tip: crowi.config.json でドライバ名を切り替えても、対応する プラグインが plugins に入っていなければ起動時に警告が出ます。ドライバを 切り替えるときは、プラグインの追加とセットで行ってください。

次のステップ

On this page