セルフホストモデル
Takuto Core は、セルフホストの OpenAI 互換モデルサーバー — LM Studio、Ollama、vLLM など — を OpenCode プロバイダー経由で動かせます。これにより、ソースコードとプロンプトを完全に あなたが管理するインフラ上にとどめられます。このページでは、セットアップと、LM Studio を Docker Desktop と組み合わせて配線する際に私たちが踏んだ失敗モードを扱うので、あなたが 同じことを再発見せずに済むようにします。
以下のすべての設定は、ダッシュボードの 設定 → AI Settings → OpenCode から編集できます。
config.tomlを手編集する必要はありません。
基本セットアップ
-
設定 → AI Settings でプロバイダーを OpenCode に設定します。
-
Model フィールドを設定します。OpenCode の
-mフラグは<providerId>/<modelId>を 期待し、Takuto Core が生成する設定は常にプロバイダーをself_hostedと名付けるので、 値は次のような形になります:self_hosted/<model-id-as-reported-by-the-server>サーバーが報告するモデル id Takuto に設定する値 qwen/qwen2.5-vl-7bself_hosted/qwen/qwen2.5-vl-7blmstudio-community/Llama-3.1-8B-Instruct-GGUFself_hosted/lmstudio-community/Llama-3.1-8B-Instruct-GGUF -
Base URL を、末尾の
/v1を含む OpenAI 互換エンドポイントに設定します:http://host.docker.internal:1234/v1 -
サーバーが本物の API キーを必要としない場合(LM Studio、Ollama は通常不要)、 Allow shared default token にチェックを入れて、Takuto Core がプレースホルダーの bearer を注入するようにします。
-
Context limit / Output limit をモデルに合わせて設定します — ローカルエンドポイントは これらを報告できないので、OpenCode はあなたが指定した値に頼ります。
モデルサーバー側
サーバーを container から到達可能にします:
- LM Studio: Developer → Local Server → “Serve on Local Network” をオンにします。
これがないと LM Studio は
127.0.0.1にしかバインドせず、どの container も到達できません。 - macOS のファイアウォール: オフにするか、モデルサーバーを明示的に許可します。
ループバックだけでなく、すべてのインターフェースにバインドされていることを確認します:
lsof -nP -iTCP -sTCP:LISTEN | grep 1234
# Want: *:1234 (LISTEN) — bound to all interfaces
# If it shows 127.0.0.1:1234, "Serve on Local Network" is OFF.
ブリッジサイドカー(gVisor 回避策)
これが必要なのは、モデルサーバーがホスト Mac 上で動き かつ Docker Desktop が gVisor ネットワークスタック(4.34+ のデフォルト)を使っている場合だけです。 クラウドプロバイダーには 不要で、モデルサーバーが Takuto Core の compose ネットワーク内の container として動く場合も 不要です — その場合は Base URL をサービス名(例:
http://lm-studio:1234/v1)に向けて、 ブリッジはスキップしてください。
gVisor では、container から Mac の LAN 上のプライベート IP への — host.docker.internal
(container 内では 192.168.65.254 に解決されます)を含む — トラフィックが、パブリック IP は
問題なく動くのに、黙ってタイムアウトすることがあります。ネットワークの種類を確認します:
ps ax | grep com.docker.virtualization | grep -o 'networkType [a-z]*'
# networkType gvisor ← affected
gVisor の問題であることを確認する
サーバーが *:1234 にバインドし、ファイアウォールがオフで、container からパブリック
インターネットには到達できるのに、container 内から host.docker.internal:1234 と Mac の
LAN IP の両方がタイムアウトする — これが gVisor スタックです。
# Public internet works from a container:
docker exec <takuto-container> sh -c 'wget -q -O - -T 3 https://1.1.1.1 | head -3'
# host.docker.internal resolves but connections time out:
docker exec <takuto-container> sh -c 'curl -v -m 3 http://host.docker.internal:1234/v1/models 2>&1 | tail -5'
# * Connection timed out after 3001 milliseconds
解決策: lm-bridge socat サイドカー
Takuto Core は、デフォルトの bridge ネットワーク(gVisor 下でもホストに正しく到達する)と
compose ネットワーク(DinD でネストされたワーカーがルーティングできるように)の 両方 に
アタッチする、小さな socat container を同梱しています。フラグ 1 つで起動できます。なお、以下の
make ターゲットは Takuto Core エンジンのリポジトリが用意する便利ラッパーです
(自分で container を構築する方法)。内部的には LM_BRIDGE=1 が
docker-compose.lm-bridge.yml を Compose スタックにマージしているだけです:
make start BACKEND=postgres LM_BRIDGE=1
これにより、固定 IP 172.20.0.250 で maestro-lm-bridge が起動し、
TCP/1234 → host.docker.internal:${LM_HOST_PORT:-1234} をフォワードします。その後、
AI Settings の Base URL を次のように設定します:
http://172.20.0.250:1234/v1
デフォルト以外のポート(たとえば Ollama の 11434)の場合:
LM_HOST_PORT=11434 make start BACKEND=postgres LM_BRIDGE=1
ブリッジが起動したらスモークテスト
docker exec maestro-core-dind-1 docker run --rm --entrypoint /bin/bash \
maestro:latest -c \
'exec 3<>/dev/tcp/172.20.0.250/1234;
printf "GET /v1/models HTTP/1.0\r\nHost: x\r\n\r\n" >&3;
timeout 5 cat <&3 | head -5'
200 OK に続いて JSON が返れば、ワーカーの経路は健全です。
OpenCode error: unknown error のチェックリスト
ダッシュボードに謎めいた OpenCode error: unknown error が表示されたら、これらを順に
確認してください — それぞれが実在する失敗モードです:
- Model フィールドが
self_hosted/で始まっている。 - Allow shared default token にチェックが入っている(ユーザーごとの bearer を保存した
場合を除く)。オフで bearer も保存されていないと、
opencode.jsonがワーカーにマウントされず、 OpenCode は初回起動時のデータベースマイグレーション直後に終了します。 - Base URL が
/v1で終わっている。 - モデルサーバーで “Serve on Local Network” がオンになっている(
127.0.0.1:<port>ではなく*:<port>)。 - Docker Desktop のネットワークが健全である — スモークテストを実行し、タイムアウトするなら
上記の
LM_BRIDGEサイドカーを使ってください。
5 つすべてが緑なのに実行がまだ失敗する場合は、container 内で opencode run を
--print-logs --log-level WARN 付きで手動実行し、隠れた「unknown error」の代わりに
OpenCode 自身の stderr を確認してください。