コンテンツにスキップ

言語の選択

現在の言語: 日本語

🐳 Docker Guide — OmniRoute

1つのコマンドでセルフホストしますか? セルフホストガイドを参照してください — docker compose -f docker-compose.selfhost.yml up -d(公開済みイメージ + Redis、ループバック限定、プロファイル選択なし)。以下のクイック実行は、 すでに別の場所でRedisを実行しているユーザー向けのシングルコンテナ構成です。

ターミナルウィンドウ
docker run -d \
--name omniroute \
--restart unless-stopped \
--stop-timeout 40 \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
ターミナルウィンドウ
# まず .env をコピーして編集
cp .env.example .env
docker run -d \
--name omniroute \
--restart unless-stopped \
--stop-timeout 40 \
--env-file .env \
-p 20128:20128 \
-v omniroute-data:/app/data \
diegosouzapw/omniroute:latest
ターミナルウィンドウ
# ベースプロファイル(CLI ツールなし)
docker compose --profile base up -d
# CLI プロファイル(Claude Code、Codex、OpenClaw を内蔵)
docker compose --profile cli up -d
# ホストプロファイル(Linux 優先、ホストの CLI バイナリを読み取り専用でマウント)
docker compose --profile host up -d
# Web プロファイル(Web セッションプロバイダー向けの Chromium/Playwright)
docker compose --profile web up -d
# CLI と CLIProxyAPI サイドカーを組み合わせる
docker compose --profile cli --profile cliproxyapi up -d

OmniRoute には、主要なデプロイ構成向けの Compose プロファイルが用意されています。環境に合ったものを選択してください。

プロファイル サービス 使用する場面 コマンド
base(デフォルト) omniroute-base ヘッドレスサーバー/最小ランタイム向け。プロバイダー CLI は含まれません docker compose --profile base up -d
cli omniroute-cli omniroute providers/setup/doctor および同梱 CLI(Codex、Claude Code、Droid、OpenClaw)を呼び出すエージェント型ワークフロー向け docker compose --profile cli up -d
host omniroute-host ~/.local/bin、~/.codex、~/.claude などを読み取り専用でマウントし、ホストの CLI へ network_mode のようにアクセスする必要がある Linux ホスト向け docker compose --profile host up -d
cliproxyapi cliproxyapi アップストリーム CLI のプロキシ用として、ポート 8317 で CLIProxyAPI サイドカーを実行する場合 docker compose --profile cliproxyapi up -d
web omniroute-web ブラウザーを必要とする Web セッションプロバイダー向け:gemini-web、claude-web、claude-turnstile(runner-web をビルドし、Chromium を含む) docker compose --profile web up -d

複数のプロファイルを組み合わせることもできます:docker compose --profile cli --profile cliproxyapi up -d。

OmniRoute を Docker で実行する際のホスト CLI ツールの設定

Section titled “OmniRoute を Docker で実行する際のホスト CLI ツールの設定”

omniroute setup-codex、setup-claude、config set <tool>、およびダッシュボードの 設定を保存ボタンは、いずれも ~/.codex/*.config.toml のようなファイルを書き込みます。これらのパスが 意味を持つのは、CLI が実際に動作しているマシン上だけです。コンテナ内で実行すると、 書き込み先はコンテナ自身のホーム(/home/node — イメージは USER node で実行されます)になります。ホスト側の CLI がそこを読み取ることはなく、 コンテナが再作成された時点で破棄されます。

OmniRoute はこの状況を検出し、使用できない成功結果を報告する代わりに、 手順を示して書き込みを拒否します。CLI は終了コード 2 で終了し、API は containerEphemeralTarget: true を含む 422 を返します。

推奨: CLI はホストで、OmniRoute は Docker で実行する

Section titled “推奨: CLI はホストで、OmniRoute は Docker で実行する”

コンテナは API を提供し、CLI はホスト上のツールを設定します。

ターミナルウィンドウ
docker compose --profile base up -d
npm install -g omniroute
omniroute connect http://localhost:20128 # CLI の接続先をコンテナに設定
omniroute setup-codex # ホスト上の実際の ~/.codex に書き込む

Codex、Claude Code、Cursor、または同様のツールをノート PC 上で実行する場合は、 これが適切な選択です。通常はこの構成になります。

代替手段: ホストの設定ディレクトリをバインドマウントする(host プロファイル)

Section titled “代替手段: ホストの設定ディレクトリをバインドマウントする(host プロファイル)”

コンテナ自体からホストの設定へ書き込みたい場合は、対象の ディレクトリをマウントし、CLI_CONFIG_HOME がマウントのルートを指すようにします。host プロファイルでは すでにこの設定が行われています。

environment:
- CLI_CONFIG_HOME=/host-home
- CLI_ALLOW_CONFIG_WRITES=true
volumes:
- ~/.codex:/host-home/.codex:rw
- ~/.claude:/host-home/.claude:rw

バインドマウントによって、パスが信頼できるものになります。OmniRoute は /proc/self/mountinfo を読み取り、マウント済みのパス(および子ディレクトリがマウントされている ディレクトリ。これはまさに上記の /host-home の構造です)への書き込みを許可する一方で、 マウントされていないパスへの書き込みは引き続き拒否します。

回避手段: コンテナ自身の CLI を設定する(必要な場合のみ使用)

Section titled “回避手段: コンテナ自身の CLI を設定する(必要な場合のみ使用)”

CLI が実際にコンテナ内に存在する場合(cli プロファイル)は、書き込みは 意図されたものです。任意の setup-* コマンドに --allow-container-write を渡すか、 サーバーに対して OMNIROUTE_ALLOW_CONTAINER_CONFIG_WRITE=true を設定します。書き込みは、 コンテナの再作成後には保持されないという警告付きで続行されます。

セキュリティ警告 — cli プロファイルと docker.sock のマウント。 cli プロファイルは /var/run/docker.sock をバインドマウントするため、コンテナ内の 自動アップデーターはホストのデーモンを使用してスタックを再作成できます (src/lib/system/autoUpdate.ts はそのソケットの存在を確認し、 存在しない場合は Docker 経由の処理をスキップします)。このソケットはホストの root 権限に関わる 信頼境界です。このソケットへアクセスできるものはすべて、root としてホストの Docker デーモンを 操作できます。つまり、ホスト上の任意のコンテナを作成、検査、停止、削除できます。 その影響は次のとおりです。

  1. cli プロファイルのポートをネットワークに公開しないでください。 127.0.0.1 上で公開してください(ports: "127.0.0.1:${DASHBOARD_PORT:-20128}:...")。 LAN から到達可能な cli プロファイルでは、ダッシュボードレベルの RCE が発生すると、 ホスト全体が侵害されます。
  2. 追加のホストディレクトリを cli プロファイルにバインドしないでください。 Docker ソケットと追加のマウントを組み合わせると、コンテナからファイルシステムとホスト設定へ 完全な読み書きが可能になります。ツールからプロジェクトを参照する必要がある場合は、 CLI バイナリを使用してローカルで実行してください。cli コンテナへはマウントしないでください。

コンテナ内での自動更新が不要な場合は、cli プロファイルを無効のままにしてください (COMPOSE_PROFILES=core,redis、またはより短い指定)。その他のプロファイルでは Docker ソケットはマウントされません。

MITM に関連する脅威モデルについては docs/security/MITM-TPROXY-DECRYPT.md (git 上にあり、/docs には組み込まれません)を、codex/claude-code/droid/openclaw バイナリの出所チェーンについては docs/security/SUPPLY_CHAIN.md を参照してください。

OmniRoute は、分散レートリミッターと共有キャッシュのバックエンドとして Redis を使用します。redis サービスは docker-compose.yml で常に定義されており(プロファイルによる制限はありません)、他のどのプロファイルとも同時に起動します。

詳細 値
イメージ redis:7-alpine
コンテナ名 omniroute-redis
内部ポート 6379
ホストポート(上書き) REDIS_PORT(デフォルトは 6379)
ホストバインド(上書き) REDIS_BIND_HOST(デフォルトは 127.0.0.1)
ボリューム omniroute-redis-data → /data
ヘルスチェック redis-cli ping(10秒間隔)

関連する環境変数:

  • REDIS_URL — アプリに注入される接続文字列(デフォルトは redis://redis:6379)。
  • REDIS_PORT — Redis コンテナのホスト側ポートマッピング。
  • REDIS_BIND_HOST — ポートを公開するホストインターフェース。デフォルトは 127.0.0.1。

デフォルトでループバックを使用する理由: サイドカーは requirepass なしで実行され、アプリ コンテナは Compose ネットワーク(redis:6379)経由で接続します。公開ポートは ホスト側のツール(redis-cli、ローカルの npm run dev)で使用するためだけにあります。 0.0.0.0 で公開すると、認証されていない Redis が LAN 上のすべてのホストに公開されます。 REDIS_BIND_HOST=0.0.0.0 を設定する場合は、サービスの command: に --requirepass も追加してください。

Redis の無効化は推奨されません(レートリミッターがインメモリのフォールバックに縮退します)。無効化する必要がある場合は、docker-compose.yml 内の redis: サービスブロックを削除またはコメントアウトするか、ゼロにスケールしてください:

ターミナルウィンドウ
docker compose up -d --scale redis=0

開発環境と並行して実行する分離された本番環境スナップショットには、docker-compose.prod.yml を使用します。

詳細 値
ファイル docker-compose.prod.yml
デフォルトのダッシュボードポート PROD_DASHBOARD_PORT=20130(内部の ${DASHBOARD_PORT:-20128} にマッピング)
デフォルトの API ポート PROD_API_PORT=20131
イメージ omniroute:prod(runner-cli ターゲットからビルド)
Redis コンテナ omniroute-redis-prod(redis:8.6.2、専用の redis-prod-data ボリューム)
データボリューム omniroute-prod-data(名前付きで、再ビルド後も永続化)
ヘルスチェック node healthcheck.mjs + redis-cli ping。depends_on は Redis の正常性を条件とする

使用方法:

ターミナルウィンドウ
# 本番環境スタックをビルドして起動
docker compose -f docker-compose.prod.yml up -d --build
# ログをストリーミング
docker compose -f docker-compose.prod.yml logs -f
# 停止して削除(ボリュームは保持)
docker compose -f docker-compose.prod.yml down

本番環境スタックは開発環境用 Compose と並行して実行されます(コンテナ名、ポート、ボリュームが異なります)。そのため、本番環境を稼働させたままローカルで反復開発を続けられます。

このリポジトリには、マルチステージ Dockerfile(Dockerfile)が含まれています。4 つのステージが公開されているため、用途に適した target を選択してください。

ステージ ベースイメージ 用途
builder node:26-trixie-slim 依存関係をインストールし(npm ci --legacy-peer-deps)、npm run build を実行します(デフォルトでは Turbopack — 下記の「ビルド時のリソース」を参照)
runner-base node:26-trixie-slim Next.js の standalone 出力を使用する本番ランタイムです。プロバイダー CLI は含まれていません。
runner-cli runner-base git、docker.io、docker-compose と、グローバル CLI の @openai/codex、@anthropic-ai/claude-code、droid、openclaw を追加します。エージェント型ワークフローにはこれを選択してください。
runner-web runner-base Web セッションプロバイダーの gemini-web、claude-web、claude-turnstile 用に、Playwright と Chromium ブラウザー(--with-deps)を追加します。これらのプロバイダーを使用する場合はこれを選択してください — 通常のイメージでは、これがないとリクエスト時に失敗します(「リリースチャネル」の -web に関する注記を参照)。

特定のターゲットを手動でビルドするには、次を実行します。

ターミナルウィンドウ
docker build --target runner-base -t omniroute:base .
docker build --target runner-cli -t omniroute:cli .
docker build --target runner-web -t omniroute:web .

builder ステージのリソース消費は、3 つのビルド引数で制御します。これらはビルド時にのみ使用されます — OMNIROUTE_MEMORY_MB(後述)は、これらとは別のランタイム設定です。

ビルド引数 デフォルト 効果
OMNIROUTE_USE_TURBOPACK 1 0 の場合は、代わりに webpack でビルドします。ピークメモリは少なくなりますが、低速です。
OMNIROUTE_BUILD_MEMORY_MB 6144 起動される next build の V8 ヒープ上限(--max-old-space-size)です。
OMNIROUTE_BUILD_WORKERS 2 CIRCLE_NODE_TOTAL に値を渡します。Next はページデータ収集用に workers = N - 1 を導出します。

大規模なビルダーで増やすべきなのは OMNIROUTE_BUILD_WORKERS であり、リソースが制限された環境で ✓ Compiled successfully の後にビルドが停止する場合に疑うべきなのもこの設定です。各ページデータワーカーはそれぞれ独立したプロセスであり、親の next build 自体も独立したプロセスです。実際の VPS での再現(issue #7518)では、各プロセスのピーク RSS が NODE_OPTIONS のヒープフラグとは無関係に約 4.5 GB であることが測定されました(Turbopack は V8 ヒープ外のネイティブ/Rust メモリでコンパイルします)。デフォルトの 2(→ 1 ワーカー、合計 2 プロセス)は、公開パイプラインで使用する 16 GB / 4 vCPU の GitHub ホステッドランナー向けに設定されています。8(→ 7 ワーカー)では、そのランナーがメモリ不足になり、buildkit は ResourceExhausted: ... cannot allocate memory でステップに失敗しました。プロセスごとの RSS を推測ではなく直接測定すると、3(→ 2 ワーカー)でもメモリに収まりませんでした。tests/unit/docker-build-memory-budget.test.ts は測定値に基づいて計算を行い、いずれかの設定値がランナーの容量を超える場合は失敗します。

Turbopack は V8 ヒープの外部にあるネイティブ Rust メモリでコンパイルするため、OMNIROUTE_BUILD_MEMORY_MB ではその使用量を制限できません。メモリ上限のあるホストでは、ビルドが OOM killer によってエラーテキストなしで SIGKILL されます。つまり、Creating an optimized production build の途中で単に停止するため、メモリ不足ではなくハングしたように見えます。ビルドホストのリソースが制限されている場合は、バンドラーを切り替えてください。

ターミナルウィンドウ
docker build --target runner-base \
--build-arg OMNIROUTE_USE_TURBOPACK=0 \
-t omniroute:base .

webpackBuildWorker が有効になっているため、next build は親プロセスとワーカープロセスを実行し、それぞれが個別に OMNIROUTE_BUILD_MEMORY_MB に従います。コンテナの上限は、その値の約 1 倍ではなく、2 倍を上回るように設定してください。

このツリーでの測定結果(--target runner-base、OMNIROUTE_BUILD_MEMORY_MB=6144):

バンドラー コンテナ上限 結果
Turbopack 8 GiB / 16 GiB どちらでも無言で OOM により強制終了
webpack 8 GiB ビルドワーカーが SIGKILL された
webpack 12 GiB 成功、ピークは 11.1 GiB

runner-base によってエクスポートされるデフォルト値:PORT=20128、HOSTNAME=0.0.0.0、OMNIROUTE_MEMORY_MB=1024、NODE_OPTIONS=--max-old-space-size=1024、DATA_DIR=/app/data、OMNIROUTE_MIGRATIONS_DIR=/app/migrations。

Docker でのメモリ動作:

  • イメージでは OMNIROUTE_MEMORY_MB=1024 を設定し、そこから NODE_OPTIONS=--max-old-space-size=1024 を導出します。
  • 実際のサーバープロセスはスタンドアロンランチャーによって起動されます。ランチャーは OMNIROUTE_MEMORY_MB を読み取り、--max-old-space-size=<OMNIROUTE_MEMORY_MB> を追加します。
  • Node は繰り返し指定された最後の --max-old-space-size の値を使用するため、OMNIROUTE_MEMORY_MB を設定することで、Docker における実効ヒープ上限を制御できます。
  • イメージでは常にこの値が設定されるため、Docker ではランチャー独自の RAM に応じたフォールバックは適用されません。ワークロードに合わせて明示的に増やしてください(下表を参照)。コーディングエージェントの /v1/responses には、2048 でもまだ小さすぎます。

コーディングエージェント向けの実行時 RAM

Section titled “コーディングエージェント向けの実行時 RAM”

Docker のデフォルトである 1 GiB は、ダッシュボードや軽量チャット向けの最低ラインであり、本番環境向けのサイズではありません。長大な POST /v1/responses の本文(数百件のメッセージ、数十個のツール)では、圧縮中に複数のインメモリグラフが保持されます。約 3 MiB/約 750k トークンのリクエストが 2 件重なると、old-space が 12 GiB でも V8 が異常終了し(FATAL ERROR: Reached heap limit)、16 GiB の cgroup OOM にも達した事例があります。#7849 を参照してください。

cgroup の --memory はヒープより大きく設定してください — ネイティブバッファ、SQLite、および圧縮処理の中間データは V8 の外部に存在します。

ワークロード OMNIROUTE_MEMORY_MB コンテナ/cgroup 備考
ダッシュボード、軽量チャット 1 件 1024(イメージのデフォルト) ≥2 GiB
コーディングエージェント 1 件(Claude/Codex/Grok) 8192 ≥10 GiB 一般的な単一セッションの /v1/responses
長大な /v1/responses を 2 件同時実行 10240–12288 ≥12–16 GiB 約 12 GiB のヒープで V8 の異常終了を計測
長いコンテキストを 3 件以上同時実行 1 プロセスでは実行しない 直列化/RAM の増設 デフォルトでは高負荷リクエストの実行中上限は 1 件です。RAM を増設せずにこの上限を引き上げると、再び異常終了が発生します

ベアメタル上の omniroute serve は、OMNIROUTE_MEMORY_MB が未設定の場合、RAM の約 35%([512, 4096] の範囲に制限)に調整します。Docker では常に 1024 が設定されるため、公式イメージではこの調整は実行されません。

ターミナルウィンドウ
docker run -d --name omniroute --restart unless-stopped --stop-timeout 40 \
-e OMNIROUTE_MEMORY_MB=8192 --memory=10g \
-p 127.0.0.1:20128:20128 -v omniroute-data:/app/data diegosouzapw/omniroute:latest

ENVIRONMENT.md に記載されているデフォルト設定に加えて、Docker 環境で実行する際には、以下の変数が特に重要です。

変数 目的 デフォルト
OMNIROUTE_WS_BRIDGE_SECRET WebSocket ブリッジ用の共有シークレット。本番環境では必須 — 強力なランダム文字列を設定してください。 未設定(指定必須)
REDIS_URL レートリミッター/キャッシュバックエンドへの接続文字列 redis://redis:6379
REDIS_PORT 同梱されている Redis コンテナのホスト側ポート 6379
REDIS_BIND_HOST 同梱されている Redis のポートを公開するホストインターフェース(AUTH を追加しない限りループバック) 127.0.0.1
AUTO_UPDATE_HOST_REPO_DIR 自動更新ワークフローのために、cli プロファイル内の /workspace/omniroute にマウントされるホストパス .(カレントディレクトリ)
OMNIROUTE_MEMORY_MB Docker スタンドアロンサーバーの実行時 Node ヒープ上限。上記のイメージデフォルトを上書きします。コーディングエージェントの場合:8192 以上(実行時 RAM を参照)。 1024
DASHBOARD_PORT / API_PORT ダッシュボード(20128)および API(20129)の公開ポートを上書き 20128 / 20129
APP_BIND_HOST docker-compose がダッシュボード/API/ライブ WS のポートを公開するホストインターフェース。REQUIRE_API_KEY=false(デフォルト)の場合、0.0.0.0 は匿名の /v1 プロキシを LAN に公開します。REQUIRE_API_KEY=true に設定するか、前段にリバースプロキシを配置する場合にのみ公開範囲を広げてください。 127.0.0.1
CLIPROXY_BIND_HOST docker-compose が cliproxyapi サイドカーを公開するホストインターフェース。このデータボリュームにはプロバイダーの認証情報が保存されます。 127.0.0.1
OMNIROUTE_PLUGINS_DIR ランタイムのプラグインスキャナーが読み取りおよびインストールに使用するディレクトリ。プラグインをバインドマウントする場合は設定してください。デフォルト値は HOME に従いますが、イメージによってはこれがエクスポートされていない場合があります。 ~/.omniroute/plugins
OMNIROUTE_BASE_PATH アプリをリバースプロキシ経由で公開する場合の URL サブパス(例:/omniroute) (空 = ルート)
NEXT_PUBLIC_BASE_URL サブパスを含む公開ブラウザーオリジン(例:https://host/omniroute) 未設定
PROD_DASHBOARD_PORT docker-compose.prod.yml 用のホスト側ダッシュボードポート 20130
CLIPROXYAPI_PORT cliproxyapi サイドカー用のホスト側ポート 8317

サブパス上のリバースプロキシ(Traefik / nginx)

Section titled “サブパス上のリバースプロキシ(Traefik / nginx)”

Next.js の basePath はスタンドアロンバンドルにコンパイルされます。OmniRoute はビルド時の値をアプリルートのセンチネルファイルに記録し(npm run build の実行中に書き込まれ、scripts/docker/ensure-docker-base-path.mjs によって読み取られます)、コンテナの起動時に OMNIROUTE_BASE_PATH と比較します。値が異なり、イメージがドメインルート用にビルドされている場合、エントリーポイントは node dev/run-standalone.mjs が実行される前に、スタンドアロンマニフェスト、埋め込まれた basePath/assetPrefix リテラル(Next 16 は SSR アセット URL を assetPrefix のみから生成するため、パッチャーはサブパスをそこにも反映します)、ビルド時に埋め込まれた /_next/static アセット URL(クライアント参照マニフェスト、メディアインポート、事前レンダリングされたエラーページ)、およびクライアント側の process.env shim を書き換えます。

.env に両方の変数を設定し、イメージとランタイムの設定が一致するように再ビルドします。

.env
OMNIROUTE_BASE_PATH=/omniroute
NEXT_PUBLIC_BASE_URL=https://myhostname.example.com/omniroute
ターミナルウィンドウ
docker compose --profile base up -d --build

docker-compose.yml は、OMNIROUTE_BASE_PATH を Docker のビルド引数およびランタイム環境変数として渡します。

ビルド済みルートイメージ + ランタイムサブパス

Section titled “ビルド済みルートイメージ + ランタイムサブパス”

公開されている diegosouzapw/omniroute:* イメージは、ドメインルート用にビルドされています。それでも、ランタイムに OMNIROUTE_BASE_PATH を設定できます。コンテナは起動時にバンドルへ一度だけパッチを適用します。対応する公開オリジンも合わせて設定してください。

services:
omniroute:
image: diegosouzapw/omniroute:latest
environment:
OMNIROUTE_BASE_PATH: /omniroute
NEXT_PUBLIC_BASE_URL: https://myhostname.example.com/omniroute

リバースプロキシは、外部パスを省略せずに完全な形で転送するように設定してください(プレフィックスを削除しないでください)。Traefik では、StripPrefix を使用せずに PathPrefix(/omniroute) をコンテナへルーティングし、Next.js が /omniroute/... を受信して /omniroute/_next/... からアセットを配信できるようにします。

Docker のヘルスチェックは、アクティブな OMNIROUTE_BASE_PATH がプレフィックスとして付加された、軽量な /healthz ライフサイクルエンドポイントをプローブします。/api/monitoring/health は、ユーザーやダッシュボードによる診断のために引き続き利用できます。コンテナの HEALTHCHECK をこのエンドポイントに戻すには(たとえば、詳細なヘルスチェックを適用する場合)、OMNIROUTE_HEALTHCHECK_PATH=/api/monitoring/health を設定します。このパスは詳細なチェック(DB + モニタリングの概要)です。オプトインする場合、実行頻度の低い Docker の HEALTHCHECK には適していますが、Kubernetes の livenessProbe の実行間隔には適していません。

オーケストレーター(Kubernetes、Nomad など)の場合:

プローブ 推奨 非推奨
Liveness HTTP GET /livez、またはメインポート(PORT、デフォルトは 20128)への TCP Liveness としての /api/monitoring/health
Readiness HTTP GET /healthz イベントループがビジーな状態を停止と見なす厳しいタイムアウト
詳細 / ブラックボックス /api/monitoring/health —

/healthz はプロセスのライフサイクル(ok / starting / stopping)を報告します。/livez はプロセスが生存しているかのみを示します(ハンドラーを実行できる限り 200 を返し、Readiness を待機しません)。どちらもリクエスト処理と同じ Node イベントループ上で実行されるため、CPU バウンドなカタログ処理や圧縮処理によって遅延する可能性があります。ビジー ≠ 停止です。HTTP プローブがタイムアウトする場合は、TCP の Liveness を推奨します。プローブに関する詳細なガイダンス: モニタリングガイド — Kubernetes プローブの推奨事項。

Caddy を使用した Docker Compose(HTTPS Auto-TLS)

Section titled “Caddy を使用した Docker Compose(HTTPS Auto-TLS)”

Caddy の自動 SSL プロビジョニングを使用して、OmniRoute を安全に公開できます。ドメインの DNS A レコードがサーバーの IP を指していることを確認してください。

services:
omniroute:
image: diegosouzapw/omniroute:latest
container_name: omniroute
restart: unless-stopped
volumes:
- omniroute-data:/app/data
environment:
- PORT=20128
# OAuth コールバック、ダッシュボードのリンク、生成される公開 URL のためのブラウザー向けオリジン。
- NEXT_PUBLIC_BASE_URL=https://your-domain.com
# スケジュールされたジョブ/自己フェッチのための内部サーバー間 URL。
- BASE_URL=http://omniroute:20128
- AUTH_COOKIE_SECURE=true
caddy:
image: caddy:latest
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
command: caddy reverse-proxy --from https://your-domain.com --to http://omniroute:20128
volumes:
omniroute-data:

Caddy は、アップストリームコンテナ向けに標準の転送ヘッダーを設定します。OmniRoute は NEXT_PUBLIC_BASE_URL を、OAuth コールバックおよび生成される公開リンクの正規の公開オリジンとして使用します。 認証済みのダッシュボード書き込みでは、同一オリジンリクエストに加えて、セッションに紐付けられた CSRF 保護が使用されます。明示的な設定ではなく、信頼済みの転送ヘッダーから OmniRoute に公開オリジンを 意図的に導出させたい高度なデプロイの場合にのみ、OMNIROUTE_TRUST_PROXY を有効にしてください。

Docker デプロイ向けのダッシュボードでは、Dashboard → Endpoints からワンクリックで Cloudflare Quick Tunnel を利用できます。初回の有効化時には、必要な場合にのみ cloudflared がダウンロードされ、現在の /v1 エンドポイントへの一時的なトンネルが開始され、生成された https://*.trycloudflare.com/v1 URL が通常の公開 URL のすぐ下に表示されます。

エンドポイントのトンネルパネル(Cloudflare、Tailscale、ngrok)は、アクティブなトンネルの状態を変更することなく、Settings → Appearance から表示または非表示にできます。

  • Quick Tunnel の URL は一時的なものであり、再起動するたびに変更されます。
  • OmniRoute またはコンテナの再起動後に、Quick Tunnel が自動的に復元されることはありません。必要に応じて、ダッシュボードから再度有効にしてください。
  • マネージドインストールは現在、x64 / arm64 上の Linux、macOS、Windows をサポートしています。
  • マネージド Quick Tunnel では、制約のあるコンテナ環境で大量に出力される QUIC UDP バッファー警告を回避するため、デフォルトで HTTP/2 トランスポートが使用されます。別のトランスポートを使用する場合は、CLOUDFLARED_PROTOCOL=quic または auto を設定してください。
  • Docker イメージにはシステム CA ルートが同梱され、マネージド cloudflared に渡されます。これにより、コンテナ内でトンネルがブートストラップされる際の TLS 信頼エラーを回避できます。
  • OmniRoute がバイナリをダウンロードする代わりに既存のバイナリを使用するようにするには、CLOUDFLARED_BIN=/absolute/path/to/cloudflared を設定してください。
イメージ タグ サイズ 説明
diegosouzapw/omniroute latest ~250MB 公開済みの安定版 SemVer のうち最高バージョン(git の main ではありません)
diegosouzapw/omniroute 3.8.0 ~250MB GitOps ではこの種類のタグに固定してください

マルチプラットフォームマニフェスト:linux/amd64 + linux/arm64 ネイティブ(Apple Silicon、AWS Graviton、Raspberry Pi)。Docker は適合するアーキテクチャを自動的に選択します。ARM ホスト上で AMD64 エミュレーションを強制する必要がある場合は、--platform linux/amd64 を指定してください。

OmniRoute は、安定版リリース、アクティブなリリースブランチのテスト、開発ビルド向けに、それぞれ個別の Docker チャンネルを公開しています。

チャンネル ソース 可変性 推奨用途
:<version> / :<version>-web 署名済み/バージョン付きリリース 不変 正確なリリースに固定する本番デプロイ
:latest / :latest-web 公開済みの安定版 SemVer のうち最高バージョン 可変の安定版ポインター SemVer の公開ジョブ後に安定版リリースへ追従します。main や未リリースの release/v* コミットには追従しません
:next / :next-web 現在のデフォルト release/v* ブランチ 可変のプレリリースポインター アクティブなリリースブランチに取り込まれたものの、まだ安定版リリースには含まれていない修正のテスト
:main / :main-web main ブランチ 可変の開発版ポインター 開発および統合テスト専用

Web セッションプロバイダー:-web イメージ

Section titled “Web セッションプロバイダー:-web イメージ”

上記の各チャンネルには、runner-web ステージからビルドされた -web タグ(:latest-web、:<version>-web、:next-web、:main-web)も用意されています。これは同じイメージに Playwright と Chromium ブラウザーを追加したものです。通常のイメージには Chromium が含まれていません。gemini-web、claude-web、claude-turnstile では Chromium が必要です。

障害は起動時ではなく、後になって発生します。これらのプロバイダーはモデルを一覧表示し、ダッシュボード上では接続済みと表示されますが、最初のリクエストでのみ次のエラーが発生します。

[500]: 外部モジュール playwright の読み込みに失敗しました: Error: モジュールが見つかりません
'/app/node_modules/playwright/node_modules/playwright-core/browsers.json'

これらのプロバイダーを使用する場合は、現在利用しているチャンネルの -web タグを pull してください。それ以外の変更は不要です。npm/CLI インストール(Docker イメージを使用しない場合)で不足する同等の要素はブラウザーバイナリです。ホスト上で npx playwright install chromium を実行してください。

プレリリースチャンネルの使用

Section titled “プレリリースチャンネルの使用”

next チャンネルは、現在のデフォルト release/v* ブランチへの push ごとに再ビルドされ、AMD64 と ARM64 の両方で公開されます。古いメンテナンスブランチがこれを上書きすることはできません。このチャンネルでは、次の安定版タグが作成される前にアクティブなリリースブランチへマージされた修正を含む、pull 可能なイメージが提供されます。

ターミナルウィンドウ
docker pull diegosouzapw/omniroute:next
docker pull diegosouzapw/omniroute:next-web

Docker Compose では、選択したプロファイルで使用するイメージタグを上書きしてから、サービスを pull して再作成します。

services:
omniroute:
image: diegosouzapw/omniroute:next
ターミナルウィンドウ
docker compose pull
docker compose up -d

next は可変のプレリリースチャンネルです。アクティブなリリースブランチへの push のたびに変更される可能性があり、本番環境での使用はサポートされていません。特定のビルドを評価する間は、イメージダイジェストに固定してください。

ターミナルウィンドウ
docker pull diegosouzapw/omniroute:next
docker image inspect diegosouzapw/omniroute:next --format '{{index .RepoDigests 0}}'

テスト前に、OmniRoute のデータボリュームまたはバインドマウントされたデータディレクトリをバックアップしてください。ロールバックするには、以前使用していた安定版バージョンまたはダイジェストを復元し、コンテナーを再作成します。

ターミナルウィンドウ
docker pull diegosouzapw/omniroute:<stable-version>
docker compose up -d

リリースブランチのビルドによって latest が更新されることはありません。安定版ポインターを更新できるのは、対象となる安定版セマンティックバージョンのみです。next イメージにも、リリースイメージの検査と CRITICAL 脆弱性をブロックするゲートが適用されます。

latest は git の最新状態を保証するものではありません。 main またはアクティブな release/v* ブランチにマージされた修正は、安定版 SemVer イメージが公開され、公開ジョブによって :latest が更新されるまで(その SemVer と同じダイジェスト)、:latest には含まれません。GitHub にはすでに修正が表示されているのに latest が更新されていないように見える場合は、:next を pull してリリースブランチをテストするか、SemVer タグが作成されるまで待ってください。

目的 使用するもの
ドリフトが許容されない GitOps/本番環境 :X.Y.Z(またはイメージダイジェスト)に固定
公開済みの安定版に追従し、リリースごとの再作成を許容する :latest
未リリースの release/v* コミットをテストする :next(本番環境では使用不可)
main をテストする :main(本番環境では使用不可)

可用性: デフォルトの SQLite は単一レプリカ

Section titled “可用性: デフォルトの SQLite は単一レプリカ”

標準の Docker / Kubernetes OmniRoute は、1 つの Node プロセス + 1 つの SQLite ライターで構成されます。このトポロジでは高可用性はサポートされていません。

制約 影響
単一ライター 同じ SQLite ファイルに対して複数のレプリカを実行しないでください。DB が破損します。
再作成 / 再起動 / HEALTHCHECK の強制終了 処理中の SSE、ダッシュボードセッション、インメモリ状態がすべて停止します。接続中のすべてのクライアントが切断されます。エンドポイントが存在しない期間中の新規リクエストには、OmniRoute JSON ではなく、リバースプロキシから 502 Bad Gateway: Unknown error が返されます。そのため、クライアントはこれをプロバイダー障害と区別できません(#11015)。
/healthz と同じイベントループ カタログ処理や圧縮処理が集中するとプローブが遅延する可能性があり、タイムアウトが短い場合は唯一のレプリカが再起動されます。

プローブマトリクス(Kubernetes のプローブ推奨事項も参照):

プローブ 対象 使用しないもの
Liveness PORT(デフォルトは 20128)への TCP、またはソフト HTTP /healthz /api/monitoring/health
Readiness HTTP GET /healthz イベントループの高負荷を停止状態として扱う短いタイムアウト
詳細確認 / 人間用 /api/monitoring/health 自動化された kubelet liveness

アップグレード: すべてのセッションが切断されることを前提としてください。可能であればクライアントをドレインしてください。デフォルトの SQLite ではローリングアップデートは利用できません。Compose の restart: unless-stopped と Docker の HEALTHCHECK を併用した場合も、コンテナが Unhealthy になると唯一のプロセスが置き換えられ、同じ範囲に影響が及びます。

単一レプリカ用の Kubernetes スニペット(Recreate が必須です。1 つの SQLite ファイルに対して replicas を増やさないでください):

spec:
replicas: 1
strategy:
type: Recreate
template:
spec:
terminationGracePeriodSeconds: 90
containers:
- name: omniroute
lifecycle:
preStop:
exec:
command: ["/bin/sleep", "15"]
readinessProbe:
httpGet:
path: /healthz
port: 20128
periodSeconds: 5
livenessProbe:
tcpSocket:
port: 20128
periodSeconds: 20

preStop の sleep により、SIGTERM の前に kube が Service エンドポイントを削除できるため、停止中のプロセスに新しいトラフィックが到達しなくなります。処理中の /v1/responses SSE は、重量級アドミッションリースを介して、最大 SHUTDOWN_TIMEOUT_MS(デフォルトは 30 秒)までドレインされます(#11015)。それでもプロセスに到達した新規リクエストには、503 と Retry-After: 5 が返されます。置き換え後のプロセスが Ready になるまでの Recreate によるエンドポイント不在期間は、引き続き完全な停止となります。これは SQLite トポロジに起因するものであり、プローブの設定ミスではありません。

外部 Postgres / マルチライター HA は、文書化された標準構成ではありません。HA が必要な場合は、単一レプリカを維持するか、プロジェクトが別途テストして文書化したトポロジを使用してください。Postgres/MySQL 対応の作業は #8075 で進められています。それがリリースされるまでは、大規模な /v1/responses の処理能力を増やすためにサポートされている唯一の方法は、N 個の独立したプロセス(次のセクション)を使用することであり、1 つのボリュームに対して replicas > 1 を設定することではありません。

スケールアウト: N 個の独立プロセス

Section titled “スケールアウト: N 個の独立プロセス”

1 つの Node プロセスは 1 つの V8 ヒープです。約 3 MiB / 約 75 万トークンのコーディングエージェントによる POST /v1/responses(RTK + Caveman)が 2 件重なると、約 12 Gi でそのヒープが異常終了し(FATAL ERROR: Reached heap limit)、16 Gi の cgroup で OOM が発生する可能性があります。#7849 を参照してください。この測定結果は メモリ予算に関する警告であり、同時実行される長時間の /v1/responses を 2 件に制限する製品上のハード上限ではありません。重量級チャットの受け入れは、同じ V8/cgroup 上限から自動算出される取り込みバイト予算(OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES、src/shared/middleware/admissionBudget.ts)によって制御されます。すでに適切にサイジングされたプロセスでこれを上方にオーバーライドする(または従来のリクエスト数上限 OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT を設定する)と、再び異常終了が発生します。小規模なチャット、/healthz、/v1/models、および MCP は、この上限の対象外です。

1 プロセス: 2 件を超える長時間の /v1/responses

Section titled “1 プロセス: 2 件を超える長時間の /v1/responses”

正常なプロセス(ヒープが OMNIROUTE_CHAT_ADMISSION_HEAP_SHED_RATIO、デフォルト 0.75 を下回る)は、プロセス全体の処理中バイト予算(OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES / #10110)にまだ余裕があれば、長時間の POST /v1/responses を 2 件を超えて同時実行できます。OMNIROUTE_CHAT_LARGE_BODY_BYTES(デフォルト 256 KiB)以上のボディは、構造的に重いリクエストと同じ重量級リースを取得し、同じ #10437 の tryAcquireHealthyHeadroom エスケープ(OMNIROUTE_CHAT_ADMISSION_HEALTHY_HEADROOM)を使用します。数十件の長時間 SSE クライアントの同時実行(運用者は多くの場合 40~50 件を必要とします)は、製品上の「最大 2 件」というハード上限ではなく、メモリ予算の問題です。ヒープ、プライマリ/ヘッドルームスロット、および OMNIROUTE_CHAT_MAX_INFLIGHT_BYTES を適切にサイジングしてください。ヒープに負荷がかかっている場合は、#7849 の再発を防ぐため、引き続き再試行可能な 503 で負荷を排除します。

ヒープを増やす(独立した V8 old-space を使用する)ために、現時点では次のようにします。

すべきこと すべきでないこと
それぞれ固有の DATA_DIR / ボリュームを持つ N 個のコンテナ/Pod を実行する 1 つの SQLite ファイルに対して replicas > 1 を設定する
ヒープ / 処理中バイト予算に基づいて、重量級の処理中リクエスト数と正常時ヘッドルームをサイジングする。1~2 件は保守的な #7849 のデフォルトであり、製品上のハード上限ではない 1 つのプロセスに 8 倍の RAM と無制限の件数上限を与える
オプション: 共有クォータカウンターには QUOTA_STORE_DRIVER=redis + QUOTA_STORE_REDIS_URL を使用する Redis を共有 SQLite として扱う — Redis は共有 SQLite ではない
プロバイダーのシークレットを各インスタンスに複製する(またはダッシュボードの分割を許容する) インスタンス間で 1 つのダッシュボード / 1 つのコールログが共有されると想定する
任意のロードバランサーを前段に配置する。API キーまたはセッション単位のスティッキー設定で十分 ベンダー固有のサイズ認識ミドルウェアを必須とする

ハードウェア: インスタンスごとの長時間 /v1/responses の同時実行数は、メモリ予算の問題です(ヒープ + 処理中バイト / #10110)。独立した DATA_DIR を持つ N 個のインスタンスでもヒープは増加します。ホスト RAM は「N=8 の 16 Gi Pod 1 個」ではなく、N × cgroup を収容できる必要があります。1 つの SQLite ファイルに対して replicas > 1 を設定してはなりません。

Compose の概略例(2 つのヒープ、2 つのボリューム — deploy.replicas: 2 ではありません):

services:
omniroute-a:
image: diegosouzapw/omniroute:3.8.49
environment:
DATA_DIR: /app/data
OMNIROUTE_MEMORY_MB: "12288"
QUOTA_STORE_DRIVER: redis
QUOTA_STORE_REDIS_URL: redis://redis:6379
volumes: [omniroute-a-data:/app/data]
ports: ["20128:20128"]
omniroute-b:
image: diegosouzapw/omniroute:3.8.49
environment:
DATA_DIR: /app/data
OMNIROUTE_MEMORY_MB: "12288"
QUOTA_STORE_DRIVER: redis
QUOTA_STORE_REDIS_URL: redis://redis:6379
volumes: [omniroute-b-data:/app/data]
ports: ["20138:20128"]
volumes:
omniroute-a-data:
omniroute-b-data:

プロセス内密度(HTTP isolate からの圧縮処理の分離)については #11023 を参照してください。共有された永続状態上の単一論理クラスターについては #8075 を参照してください。

  • SQLite WALモード: OmniRouteが最新の変更をstorage.sqliteへチェックポイントできるように、docker stopが完了するまで待機してください。同梱のComposeファイルでは、停止猶予期間がすでに40秒に設定されています。イメージを直接実行する場合は、--stop-timeout 40を指定してください。
  • DISABLE_SQLITE_AUTO_BACKUP: 定期バックアップや書き込み前バックアップを外部で管理している場合は、trueに設定してください。既存データベースのマイグレーションでは、引き続き独自の永続的な安全スナップショットと一括マイグレーション保護が必要です。
  • データの永続化: コンテナの再起動後もデータベース、キー、設定を保持するには、必ず/app/dataにボリュームをマウントしてください。
  • ポート設定: デフォルトの20128ポートを変更するには、PORT環境変数を上書きしてください。

undefined (a58000c7685f)

HagiCode

HagiCode はエージェント型コーディングワークスペースです。豊富で便利な UI インタラクションにより、計画・エージェント実行・プロジェクト作業を始めやすく、進めやすくし、開発をより魅力的な体験にします。

豊富で便利な UI インタラクションで、計画からプロジェクト作業までを分かりやすく進められます。

HagiCode を見るドキュメントを読む
  • スマートOpenSpec ワークフローが意図を、提案・設計・タスクから変更のリリースまで実行可能な道筋にします。
  • 効率的マルチエージェント実行で調査・実装・レビューを並行して進め、複数リポジトリや使い慣れた Agent CLI にも対応します。
  • 興味深い豊富で便利な UI インタラクションにより、計画・エージェント実行・プロジェクト作業を始めやすく、進めやすくします。

Windows 版をダウンロード

Microsoft Store で入手すべてのダウンロード

アイデアを、出荷できるソフトウェアへ。

HagiCode はエージェント型コーディングワークスペースです。OpenSpec ワークフローで変更を計画し、マルチエージェント実行で進め、Hero Scenario で長い作業の進み具合を見える化して、アイデアを出荷できるソフトウェアにします。

スマート
OpenSpec ワークフローが、意図を提案からリリースまでの実行可能な道筋にします。
効率的
マルチエージェント実行で、調査・実装・レビューを並行して進めます。
楽しい
使いやすい UI で、計画・Agent 実行・プロジェクト作業を進めやすくします。