環境変数
セルフホストの Multica サーバーを実行するための環境変数の完全な一覧です。
セルフホストの Multica サーバーは、起動時に環境変数から設定を読み込みます — データベース、サインイン、メール、ストレージ、サインアップ許可リストはすべてここにあります。このページでは、すべての変数を用途別にグループ化しています。各セクションでは、設定しないと何が起きるか、そしてプロダクションで必ず設定すべきものはどれかを明確に説明します。auth 関連の変数を実際にどう設定するかについては、サインインとサインアップの設定を参照してください。
コアサーバー変数
デプロイ前に必ず検討すべきコア変数です — 一部はサーバーを起動できるようにするデフォルト値を持っていますが、プロダクションでは必須項目を明示的に設定すべきです。
| 変数 | デフォルト | プロダクションで必須? |
|---|---|---|
DATABASE_URL | postgres://multica:multica@localhost:5432/multica?sslmode=disable | はい |
PORT | 8080 | いいえ(ポートを変更する場合を除く) |
JWT_SECRET | multica-dev-secret-change-in-production | はい(デフォルトは安全ではありません) |
APP_ENV | 空 | はい(production である必要があります) |
FRONTEND_ORIGIN | 空 | はい(セルフホストは自身のドメインを設定する必要があります) |
MULTICA_DEV_VERIFICATION_CODE | 空 | いいえ(プロダクションでは必ず空のままにしてください) |
プロダクションでは MULTICA_DEV_VERIFICATION_CODE を空のままにしてください。 固定のローカルテストコードはデフォルトで無効になっていますが、MULTICA_DEV_VERIFICATION_CODE=888888 で有効にすると、APP_ENV が production 以外の間は、コードを要求できる誰もがその固定値でサインインできてしまいます。このショートカットは APP_ENV=production のときには無視されます。
データベース接続プール
| 変数 | デフォルト | 説明 |
|---|---|---|
DATABASE_MAX_CONNS | 25 | pgxpool の最大接続数。デーモンは頻繁に(3 秒ごとに)ポーリングして接続を使用するため、規模の大きいデプロイではより高い値が必要になる場合があります |
DATABASE_MIN_CONNS | 5 | 最小アイドル接続数 |
設定しない場合、上記の値が使われます — 以前プロダクションでプール枯渇を引き起こした pgx 組み込みの 4/NumCPU デフォルトではありません。
メール設定
Multica は 2 つの配信バックエンドをサポートします — クラウドデプロイ向けの Resend と、内部 / オンプレミスネットワーク向けの SMTP relay です。両方が設定されている場合は SMTP_HOST が RESEND_API_KEY より優先されます。
Resend
| 変数 | デフォルト | 説明 |
|---|---|---|
RESEND_API_KEY | 空 | Resend API key |
RESEND_FROM_EMAIL | noreply@multica.ai | 送信元アドレス(Resend アカウントで検証済みのドメインである必要があり、SMTP を使用する場合も From: ヘッダーとして再利用されます) |
SMTP relay
| 変数 | デフォルト | 説明 |
|---|---|---|
SMTP_HOST | 空 | SMTP relay のホスト名。これを設定すると SMTP モードが有効になり、Resend を上書きします |
SMTP_PORT | 25 | SMTP ポート。STARTTLS サブミッションには 587 を、SMTPS(暗黙的 TLS、自動有効化)には 465 を使用します |
SMTP_USERNAME | 空 | SMTP ユーザー名。認証なしの relay の場合は空のままにしてください |
SMTP_PASSWORD | 空 | SMTP パスワード |
SMTP_TLS | starttls | TLS モード。implicit(別名 smtps、ssl)は接続時に即座に TLS ハンドシェイクを行います(SMTPS)。465 ポートでは自動的に有効になります。未設定 / starttls の場合は接続後に STARTTLS でアップグレードします |
SMTP_TLS_INSECURE | false | TLS 証明書の検証をスキップするには true に設定(プライベート CA / 自己署名証明書のみ) |
SMTP_EHLO_NAME | マシンのホスト名 | relay に通知する EHLO/HELO 名。厳格な relay(例: Google Workspace smtp-relay.gmail.com)が公開 IP からのデフォルトの挨拶を拒否する場合は、実際の FQDN を設定してください — そうしないと relay が接続を切断し、後続のコマンドで不明瞭な EOF として表面化します |
サーバーが STARTTLS を通知すると自動的にアップグレードされます。dial タイムアウトは 10 秒で、SMTP セッション全体には 30 秒のデッドラインがあるため、ブラックホール化した relay が auth ハンドラーをハングさせることはできません。
どちらも設定していない場合の動作: サーバーはエラーを出しませんが、送信されるはずだったすべてのメール(検証コード、招待リンク)はサーバーの stdout にのみ記録されます。ローカル開発には便利です — サーバーログからコードをコピーして使ってください。プロダクションでこれを設定し忘れると、静かなブラックホールが生まれ、ユーザーはメールをまったく受け取れず、エラーも一切表面化しません。
Google OAuth 設定
任意です。メール + 検証コードのみを使用する場合は設定しないままにし、サインインページに「Sign in with Google」を追加する場合は設定してください。
| 変数 | デフォルト | 説明 |
|---|---|---|
GOOGLE_CLIENT_ID | 空 | Google Cloud OAuth client ID |
GOOGLE_CLIENT_SECRET | 空 | Google Cloud OAuth secret |
GOOGLE_REDIRECT_URI | http://localhost:3000/auth/callback | OAuth コールバック URL(セルフホスト: 自身のフロントエンドドメインに置き換えてください) |
ランタイムで適用されます: フロントエンドはこれらの設定をランタイムに /api/config 経由で読み込むため、変更してもフロントエンドのリビルドや再デプロイは不要です — サーバーを再起動すれば適用されます。
完全なセットアップ(Google Cloud Console の手順を含む)はサインインとサインアップの設定にあります。
ファイルストレージ設定
Multica はユーザーがアップロードした添付ファイル(コメント内の画像やファイル)を保存します。S3 が推奨されます。S3 が設定されていない場合はローカルディスクにフォールバックします。
S3 / S3 互換ストレージ
| 変数 | デフォルト | 説明 |
|---|---|---|
S3_BUCKET | 空 | バケット名のみ(例: my-bucket)。.s3.<region>.amazonaws.com サフィックスは含めないでください — サーバーが S3_BUCKET + S3_REGION から公開ホストを構築します。これを設定すると S3 ストレージが有効になります |
S3_REGION | us-west-2 | AWS リージョン。バケットの実際のリージョンと一致する必要があります — SDK 署名と公開 URL の構築の両方に使われます |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | 空 | 静的な認証情報。両方を設定しない場合は AWS SDK のデフォルト認証情報チェーン(IAM role / 環境認証情報)が使われます |
AWS_ENDPOINT_URL | 空 | カスタムの S3 互換エンドポイント(例: MinIO)。これを設定すると path-style URL に切り替わります |
ATTACHMENT_DOWNLOAD_MODE | auto | 添付ファイルのダウンロード方式: auto、cloudfront、presign、proxy。auto では CloudFront が完全に設定されている場合は優先し、内部/プライベート endpoint host は server proxy、公開 S3 互換 endpoint は対応時に presigned GET を使います |
ATTACHMENT_DOWNLOAD_URL_TTL | 30m | CloudFront signed URL と S3 presigned download URL の有効期間。Go duration 形式を受け付けます |
S3_BUCKET を設定しない場合: サーバーは起動時に "S3_BUCKET not set, cloud upload disabled" をログに記録し、すべてのアップロードはローカルディスクにフォールバックします。
保存されるオブジェクト URL は次の優先順位で構築されます。
CLOUDFRONT_DOMAINが設定されている場合はhttps://<CLOUDFRONT_DOMAIN>/<key>。AWS_ENDPOINT_URLが設定されている場合は<AWS_ENDPOINT_URL>/<S3_BUCKET>/<key>(path-style)。https://<S3_BUCKET>.s3.<S3_REGION>.amazonaws.com/<key>(virtual-hosted-style)。S3_BUCKETにドットが含まれる場合、AWS が発行するワイルドカード TLS 証明書がドットを含むバケットホストを検証できないため、サーバーはhttps://s3.<S3_REGION>.amazonaws.com/<S3_BUCKET>/<key>(path-style)にフォールバックします。
API の download_url は、CloudFront 署名が設定されていない場合 GET /api/attachments/{id}/download を使います。この endpoint は安全な場合 CloudFront/S3 presigned URL にリダイレクトし、http://rustfs:9000 のようなプライベート/内部 endpoint では server がストリーミングします。Docker/VPC 内部のオブジェクトストアでは ATTACHMENT_DOWNLOAD_MODE=proxy を明示できます。
ローカルディスク(S3 が設定されていない場合)
| 変数 | デフォルト | 説明 |
|---|---|---|
LOCAL_UPLOAD_DIR | ./data/uploads | ローカルストレージのディレクトリ |
LOCAL_UPLOAD_BASE_URL | 空(相対パスを返します) | 公開 base URL — 設定しないとフロントエンドが添付ファイルの完全な URL を解決できません |
CloudFront(任意)
S3 の前段に CloudFront を置く場合、3 つの変数が適用されます: CLOUDFRONT_DOMAIN、CLOUDFRONT_KEY_PAIR_ID、CLOUDFRONT_PRIVATE_KEY(または Secrets Manager から読み込むには CLOUDFRONT_PRIVATE_KEY_SECRET)。CloudFront を使わない場合はスキップしてください — S3 設定とは競合しません。
Cookie ドメイン
| 変数 | デフォルト | 説明 |
|---|---|---|
COOKIE_DOMAIN | 空 | セッション cookie のスコープ |
- 空: cookie は訪問した正確なホストでのみ有効です(単一ホストのデプロイに適切)
.example.comに設定: cookie がサブドメイン間で共有されます(そのためapp.example.comとapi.example.comがサインインセッションを共有します)- 警告: IP アドレスにはできません(ブラウザは無視します)
誰がサインアップできるかを制限する
3 つの許可リストの層が優先順位に従って組み合わされます。いずれか 1 つの層でも空でない値に設定されると、一致しないメールは拒否されます — ALLOW_SIGNUP=true でさえこれを上書きできません。
| 変数 | デフォルト | 説明 |
|---|---|---|
ALLOWED_EMAILS | 空 | 明示的なメール許可リスト(カンマ区切り)。空でない場合、リストにあるメールのみがサインアップできます |
ALLOWED_EMAIL_DOMAINS | 空 | ドメイン許可リスト(カンマ区切り)。空でない場合、リストにあるドメインのみがサインアップできます |
ALLOW_SIGNUP | true | サインアップのマスタースイッチ。サインアップを完全に無効にするには false に設定 |
直感に反する部分: ALLOWED_EMAIL_DOMAINS=company.io + ALLOW_SIGNUP=true は「company.io または全員を許可」という意味ではなく、company.io のみを許可という意味です。許可リストの層は AND セマンティクスです — 完全な決定木はサインインとサインアップの設定 → サインアップ許可リストにあります。
招待フロー自体はサインアップ許可リストをチェックしません — ただし、招待された人は招待を承諾する前に依然としてサインインできる必要があります。すでに Multica アカウントを持っている場合(例: 別のワークスペースから)、許可リストの影響を受けずに直接承諾できます。一度もサインアップしたことがない場合、サインインの最初のステップ(検証コードの要求)は依然として許可リストのチェックを通過し、ALLOW_SIGNUP=false や ALLOWED_EMAILS / ALLOWED_EMAIL_DOMAINS によって拒否されたメールはサインアップを完了できず、したがって招待を承諾できません。
ワークスペース作成をロックダウンする
ALLOW_SIGNUP=false は新しいアカウントをブロックしますが、すでにサインイン済みのユーザーが POST /api/workspaces 経由で別のワークスペースを作成することはブロックしません。すべてのイシュー、リポジトリ、エージェントがプラットフォーム管理者に見えなければならないセルフホストインスタンスでは、そのギャップを塞ぐために DISABLE_WORKSPACE_CREATION=true を設定してください。
| 変数 | デフォルト | 説明 |
|---|---|---|
DISABLE_WORKSPACE_CREATION | false | true の場合、POST /api/workspaces へのすべての呼び出しが 403 workspace creation is disabled for this instance を返します。Web UI は /api/config 経由ですべての「ワークスペース作成」要素を非表示にします。役割 / owner の例外はありません — このゲートはインスタンス単位で全体に適用されます |
推奨されるブートストラップ手順:
DISABLE_WORKSPACE_CREATIONを設定しないまま(デフォルト)インスタンスを起動します。- 管理者としてサインインし、共有ワークスペースを作成します。
DISABLE_WORKSPACE_CREATION=trueを設定してバックエンドを再起動します。この時点から、ユーザーは招待によってのみ参加できます。
招待されたユーザーが最初の検証コードでサインアップを完了できるよう ALLOW_SIGNUP=true を維持したい場合は、DISABLE_WORKSPACE_CREATION=true を ALLOWED_EMAIL_DOMAINS / ALLOWED_EMAILS と組み合わせて、どのアドレスがサインアップできるかの範囲を指定してください。ALLOW_SIGNUP=false を設定すると、保留中の招待対象者がアカウントを作成すること自体も追加でブロックされます — すべてのメンバーがすでに Multica アカウントを持っているインスタンスでのみ有用です。
レート制限(任意の Redis)
公開 auth エンドポイント — /auth/send-code、/auth/verify-code、/auth/google — の前段には、IP ごとの固定ウィンドウのレート制限があります。リミッターは Redis によって支えられています。REDIS_URL を設定しない場合、ミドルウェアは no-op(fail-open)になり、バックエンドは起動時に rate limiting disabled: REDIS_URL not configured をログに記録します。
| 変数 | デフォルト | 説明 |
|---|---|---|
REDIS_URL | 空 | Redis 接続 URL(例: redis://localhost:6379/0)。設定しないと auth エンドポイントのレート制限が無効になります。同じ Redis はリアルタイムハブの fan-out、PAT キャッシュ、デーモントークンキャッシュでも使われます — 設定しない場合はすべてインメモリ / 直接 DB モードにフォールバックします |
RATE_LIMIT_AUTH | 5 | /auth/send-code および /auth/google に対する IP あたり毎分の最大リクエスト数 |
RATE_LIMIT_AUTH_VERIFY | 20 | /auth/verify-code に対する IP あたり毎分の最大リクエスト数 |
RATE_LIMIT_TRUSTED_PROXIES | 空 | リミッターがその X-Forwarded-For ヘッダーを信頼することを許可する、カンマ区切りの CIDR。空(デフォルト)は XFF を決して信頼しないことを意味します — リミッターは直接接続の RemoteAddr のみを使用します |
リクエストが制限を超えると、サーバーは 429 Too Many Requests、Retry-After: 60、そして本文 {"error":"too many requests"} で応答します。
リバースプロキシの背後では RATE_LIMIT_TRUSTED_PROXIES を必ず設定する必要があります。 そうしないと、バックエンドの観点ではすべての実際のユーザーがプロキシの IP を共有することになり、デプロイ全体が 1 つのバケットに入り、/auth/send-code がサイト全体で毎分 5 リクエストになってしまいます。一般的な値: 同一ホストの Caddy / Nginx には 127.0.0.1/32,::1/128、Cloudflare / ALB / CloudFront には該当 CDN が公開している IP 範囲。RemoteAddr がこれらの CIDR のいずれかに含まれる IP のみが、X-Forwarded-For を使ってクライアントを識別できます。
この独立した RATE_LIMIT_TRUSTED_PROXIES は、オートパイロット webhook リミッター(/api/webhooks/autopilots/{token})を制御する MULTICA_TRUSTED_PROXIES とは異なります。各リミッターは自身のリストをパースするため、プロキシの背後にあるデプロイは両方を設定すべきです。
デーモンのチューニングパラメータ
デーモンはユーザーのローカルマシン上で実行され、その設定もローカル環境変数から読み込まれます。一般的なものは次のとおりです。
| 変数 | デフォルト | 説明 |
|---|---|---|
MULTICA_SERVER_URL | ws://localhost:8080/ws | サーバーアドレス(セルフホスト: 自身のドメインに置き換えてください) |
MULTICA_DAEMON_HEARTBEAT_INTERVAL | 15s | ハートビート間隔 |
MULTICA_DAEMON_POLL_INTERVAL | 3s | タスクのポーリング間隔 |
MULTICA_DAEMON_MAX_CONCURRENT_TASKS | 20 | 最大同時タスク数 |
MULTICA_<PROVIDER>_PATH | CLI 名に一致 | 各 AI コーディングツールの実行ファイルへのパス(例: MULTICA_CLAUDE_PATH) |
MULTICA_<PROVIDER>_MODEL | 空 | 各 AI コーディングツールのデフォルトモデル |
各パラメータがデーモンの動作にどう影響するかの完全な説明は、デーモンとランタイムを参照してください。
フロントエンドのアクセス制御
| 変数 | デフォルト | 説明 |
|---|---|---|
FRONTEND_ORIGIN | 空 | フロントエンドアドレス。招待メールのリンク、CORS 許可リスト、cookie ドメインはすべてこの値から派生します。設定しない場合、招待メールのリンクはホスト型ドメイン https://app.multica.ai にフォールバックします — セルフホストはこれを明示的に設定する必要があります |
CORS_ALLOWED_ORIGINS | 空 | 追加で許可する CORS origin(カンマ区切り) |
ALLOWED_ORIGINS | 空 | WebSocket 専用の origin 許可リスト(カンマ区切り)。設定しない場合、フォールバック順序は CORS_ALLOWED_ORIGINS → FRONTEND_ORIGIN → localhost:3000/5173/5174 です |
FRONTEND_ORIGIN を設定しないと 2 つの静かな失敗が発生します: (1) 招待メールのリンクが https://app.multica.ai(ホスト型ドメイン)を指し、クリックしてもユーザーがセルフホストインスタンスに戻ってこない。(2) WebSocket の Origin チェックが localhost:3000 / 5173 / 5174 にフォールバックするため、プロダクションデプロイのすべての WebSocket 接続が拒否され、フロントエンドが「リアルタイム更新を受け取れない」ように見える。
GitHub 連携
GitHub PR ↔ イシュー連携には 2 つの変数が必要です。設定で Connect GitHub を有効にし、受信 webhook を受け付けるには両方を設定してください。
| 変数 | デフォルト | 説明 |
|---|---|---|
GITHUB_APP_SLUG | 空 | GitHub App の slug(https://github.com/apps/<slug> の末尾部分)。設定 → GitHub のインストールボタン URL を構成します |
GITHUB_WEBHOOK_SECRET | 空 | GitHub App に設定した Webhook secret。すべての pull_request / installation delivery の HMAC-SHA256 検証に使われ、setup コールバックの state token の HMAC キーとしても使われます |
どちらかが設定されていない場合の動作:
- 設定 → GitHub の
Connect GitHubが無効になり、admin に「not configured」というヒントを表示します。 /api/webhooks/githubエンドポイントは503 github webhooks not configuredを返します — Multica はすべての署名を有効として扱うのではなく、secret なしではイベント処理を拒否します。
注: GITHUB_WEBHOOK_SECRET はインストールフローの state token の署名キーとして再利用されるため、運用者は secret を 1 つだけ管理すればよいです。これは GitHub App の Client secret ではありません — Client secret は OAuth 関連であり、この連携では使われません。完全な手順は GitHub 連携 → セルフホストのセットアップを参照してください。
使用量分析
デフォルトでは、サーバーは Multica の公式 PostHog インスタンスにレポートします。オプトアウトするには ANALYTICS_DISABLED=true を設定してください。
| 変数 | デフォルト | 説明 |
|---|---|---|
ANALYTICS_DISABLED | false | バックエンド分析を完全に無効にするには true に設定 |
POSTHOG_API_KEY | 組み込みのデフォルトキー | 自身の PostHog インスタンスを指す場合に設定 |
POSTHOG_HOST | https://us.i.posthog.com | PostHog をセルフホストする場合は自身のホストに変更 |
次へ
- サインインとサインアップの設定 — 上記の auth 関連変数を実際にどう設定するか、そして落とし穴がどこにあるか
- GitHub 連携 —
GITHUB_APP_SLUG/GITHUB_WEBHOOK_SECRETを支える GitHub App をどうセットアップするか - トラブルシューティング — よくある設定ミスの症状と対処法
- デーモンとランタイム —
MULTICA_DAEMON_*パラメータが実際に何をするか