読了時間 : 14 minutes

2つのProサブスクリプション、1台のマシン、1枚の銀行カード、そしてネットワーク競合ゼロ。Docker が 2 台 目の PC を 買わ ず に クラウド 推論 能力 を 2 倍 に する 方法 を 私 に 教え た。

はじめに

私は数ヶ月間、Ollama Proを使ってOpenCodeのセッションにクラウドモデルを提供してきました。問題は、Proプランでも並行して複数のエージェントを起動するとすぐに*レートリミット*に達してしまうことです。明らかな解決策:もう一つのサブスクリプション。

でも、これが悲劇だ。

Ollamaは各マシンを一意のSSHキーで識別します — それが有名な*Device Key*です。同じOS上の2つのインスタンスは同じアイデンティティを共有し、同じデバイスに2つのProアカウントをリンクすることは不可能です。そしてあなたが予想するように、そのためだけにもう1台のラップトップを買うつもりはありませんでした。

解決策 : 不正行為をする。 Ollama が異なる2台のマシンで動作していると誤認させる。実際には同じ CPU、同じ RAM、同じネットワーク接続を共有している。 Docker は完璧な隔離バブルを提供してくれる。

@startuml
!theme plain
skinparam BoxPadding 10
skinparam DefaultFontSize 12

left to right direction

node "物理的機械" {
  frame "Ollama インスタンス A (ネイティブ)" as Native {
    database "アイデンティティ\n/usr/share/ollama/.ollama/id_ed25519" as KeyA
    portin "API
:11434" as PortA
  }

  frame "Ollama インスタンス B (Docker)" as Docker {
    database "Identité\n~/ollama-b-data/id_ed25519" as KeyB
    portin "API\n:11435" as PortB
  }
}

cloud "Ollama クラウド" {
  actor "プロアカウント A
(メール 1)" as AccountA
  actor "プロ B アカウント
(email 2)" as AccountB
}

KeyA --> AccountA : "SSHキー A"
KeyB --> AccountB : "SSHキー B"
PortA --> AccountA : "クエリー A"
PortB --> AccountB : "リクエスト B"

note bottom of Docker
  Conteneur isolé : identité SSH distincte,
  port réseau distinct, volume persistant
end note
@enduml

なぜ同じことを二度するのですか?

私を精神病者扱いする前に、ユースケースを説明させてください。

Proプランの単一のサブスクリプションだけで、私はモデルを起動することができます、たとえば`deepseek-v4-pro:cloud`OpenCode のセッションでは。問題が起きるのは、*二つ*のセッションを同時に使いたいときです。レートリミットのクォータにより、2番目のセッションが遅くなるか、完全に拒否されます。

2つの独立したProサブスクリプションがあります:

  • セッション OpenCode 1 → プロアカウント A`localhost:11434`)

  • セッション OpenCode 2 → プロアカウント B`localhost:11435`)

各セッションはそれぞれ独自の割り当てと独自のコンテキストを持ち、他のセッションに影響を与えません。これは人間のマルチプロセッシングです。

Proサブスクリプション2つ = 異なるメールアドレス2つ。 同じ銀行カードは機能します — Ollamaの支払いシステムは、同じ支払い方法からの複数のサブスクリプションをブロックしません。 私は確認しました。

問題の核心 : デバイスキー

Ollamaをインストールすると、アイデンティティディレクトリにed25519のSSHキーのペアが生成されます:

$ cat /usr/share/ollama/.ollama/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...

このキーはOllamaのサーバーにアップロードされます、の際に`ollama signin`. 彼女は言う:「このマシンは特定のProアカウントに属しています。」 もしあなたの2つのインスタンスが同じファイルを共有している場合`id_ed25519`彼らは同じアイデンティティを共有しています。ゲーム終了。

パレード:2番目のインスタンスに独自のアイデンティティディレクトリを与える、Dockerボリューム内に隔離された

準備 — 手順ごと

前提条件

  • 機能的な Ollama のネイティブインストール(公式スクリプト`curl | sh`)

  • Dockerがインストールされており、機能しています。

  • Portainer または docker-compose を使用したデプロイ

  • 2つのOllamaアカウントと2つの異なるメールアドレス

私はバージョンを使いました`0.20.2`— 公式スクリプトによって提供されるものおよび対応するDockerイメージ。

ステップ 1:ボリュームを作成

ホスト上の単純なディレクトリは、インスタンス B のアイデンティティの永続ボリュームとして機能します :

mkdir -p ~/ollama-b-data

このフォルダーはDockerコンテナーとしてマウントされます`/root/.ollama`、そこでオラマがアイデンティティキー、履歴、およびモデルを保存している

ステップ 2 : Docker コンテナーを起動

# docker-compose.yml
services:
  ollama-instance-b:
    image: ollama/ollama:0.20.2
    container_name: ollama-instance-b
    ports:
      - "11435:11434"
    volumes:
      - /home/cheroliv/ollama-b-data:/root/.ollama
    environment:
      - OLLAMA_HOST=0.0.0.0
    restart: always

ここで起きていること:

  • 港11435ホストは …​ にマッピングされます11434コンテナの内部。それにより、Docker インスタンスはリッスンします。:11435`ネイティブなインスタンスが居座っているにもかかわらず、衝突なく:11434`。

  • ボリューム`~/ollama-b-data`に取り付けられている`/root/.ollama`— ここで SSH のアイデンティティが保存されます。

  • `OLLAMA_HOST=0.0.0.0`コンテナが外部接続を受け入れることを許可する。

私はPortainerを使ってこのスタックをデプロイしましたが、単純な`docker compose up -d`同様に機能します。

ステップ 3: 公開鍵を取得

コンテナが初回起動時に空であるため、Ollama はボリューム内に新しい SSH キーペアを自動的に生成します。公開鍵を取得します:

$ docker exec ollama-instance-b cat /root/.ollama/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDDQ+dvnfmuo49q5O8LOlvgZ39SKORFw47ry9k4H2jPc

このキーがネイティブインスタンスのものと*異なる*ことを確認します:

# Instance native
$ cat /usr/share/ollama/.ollama/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGyF...(différente)

# Instance Docker
$ cat ~/ollama-b-data/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDDQ...(différente)

�異なる二つの鍵、別々の二つのアイデンティティ。やり遂げた。

コンテナが再起動しても、ボリューム内のキーを 再利用 します。アイデンティティは永続的です。Pro アカウントとの関連付けを失うことはありません。

ステップ4:Ollama.comでキーを登録

https://ollama.com/settings/keys の方向 → SSH キーを追加。 Docker インスタンスの公開鍵を貼り付けて確認します。

次に、このアイデンティティを Pro B アカウントにリンクします :

$ docker exec -it ollama-instance-b ollama signin

ブラウザーが起動し、B アカウントのメールでログインし、トークンがコンテナの SSH キーに関連付けられます。すべてが問題ないことを確認します:

$ docker exec -it ollama-instance-b ollama signin
User: cherolivpro

ステップ 5:小さな無料モデルでテストする

Proサブスクリプションの価格を挙げる前に、パイプが正常に機能していることを確認したい。接続を検証するために、ローカルの小さな無料モデルをpullする:

$ docker exec ollama-instance-b ollama pull qwen3:0.6b
pulling manifest
pulling 7f4030143c1c: 100% ▕██████████████████▏ 522 MB
success

$ curl -s http://localhost:11435/api/tags
{"models":[{"name":"qwen3:0.6b","model":"qwen3:0.6b",...}]}

港`11435`答える、モデルは提供されている。 インスタンスBは生きている。

安心したら、私は本当のクラウドProモデルのプルに移ります:

$ docker exec ollama-instance-b ollama pull deepseek-v4-pro:cloud
pulling manifest
pulling 31c3059e137e: 100% ▕██████████████████▏  344 B
success

344オクテットはクラウドモデルのマニフェスト用です — 通常、推論はサーバーサイドで行われ、ローカルではありません。そしてこれが究極のテストです:

$ curl -s http://localhost:11435/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-v4-pro:cloud","messages":[{"role":"user","content":"Dis bonjour en une phrase courte."}]}'

{
  "id": "chatcmpl-480",
  "model": "deepseek-v4-pro",
  "choices": [{
    "message": { "content": "Bonjour !" },
    "finish_reason": "stop"
  }],
  "usage": { "total_tokens": 181 }
}

こんにちは、あなたにも、インスタンスB

API /v1/models の罠

愚かな細かいことで20分を無駄にした。 プロバイダーを設定したとき`ollama-b`OpenCode では、モデルセレクターに何も表示されませんでした。何も。まったく。

理由は? API`/v1/models`Bインスタンスが返した`{"object":"list","data":null}`代わりに`{"object":"list","data":[]}`どのモデルもプルされていなかったとき。値`null`OpenCode側のパースがクラッシュし、プロバイダーが表示されなかった。

解決策:OpenCodeの設定でモデルを*明示的に*宣言し、動的な発見に依存しないようにする。

~/.config/opencode/opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama (local)",
      "options": { "baseURL": "http://localhost:11434/v1" },
      "models": {
        "gemma4:e2b": { "name": "Gemma 4 E2B (local)" }
      }
    },
    "ollama-b": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ollama Instance B (Docker)",
      "options": { "baseURL": "http://localhost:11435/v1" },
      "models": {
        "qwen3:0.6b": { "name": "Qwen3 0.6B (B)" },
        "deepseek-v4-pro:cloud": { "name": "DeepSeek V4 Pro (B)" }
      }
    }
  }
}

この明示的な宣言により、OpenCodeはすぐにプロバイダーBとそのモデルを認識します。セッションを再起動すると、セレクター`/models`両方のインスタンスを横に並べて表示します。

あなたの provider custom が表示されない場合の中に`/models`, ターミナルの再起動に3時間も費やさないでください。モデルを手動で宣言してください 中に`opencode.json`— それは問題を瞬時に解決します。

結果:2つのセッション、2つのアカウント、ゼロコンフリクト

最終的に、私はOpenCodeのセッションを2つ同時に起動できます :

Session 1 → /models → Ollama (local) → deepseek-v4-pro:cloud → Compte A
Session 2 → /models → Ollama Instance B (Docker) → deepseek-v4-pro:cloud → Compte B

各セッションはそれぞれ独自のクォータとレートリミットを持ち、互いに干渉しません。同じマシン、同じブルーカード、でもメールアドレスは2つ異なります。

そして最高なのは? Dockerコンテナは`restart: always`. システムの再起動後も手動介入なしで生き残ります。

学んだ教訓

  1. Dockerは全てを隔離する、アイデンティティさえも— ボリュームのシンプルなバインドマウントで、コンテナに独自のSSHキーのセットを与えることができ、Ollamaの目には物理的に異なるマシンと区別がつかなくなります。

  2. 2通のメール、同じCBOllamaは同じ支払い方法からの複数のサブスクリプションをブロックしません。メールアドレスのみが異なる必要があります。

  3. 支払う前に無料でテスト — Un ollama pull qwen3:0.6b (modèle libre, 522 Mo) permet de valider toute la chaîne réseau sans débourser un centime. Vous validez le plomberie d’abord, vous activez le Pro ensuite.

  4. /v1/models` と data: null は OpenCode を壊します— カスタムプロバイダーを設定するときに`"models": {}`, OpenCodeはAPIを通じてモデルの発見を試みます。APIが応答した場合`data: null`, プロバイダーが表示されません。モデルを明示的に宣言してください。

  5. 2つのアカウント、それは人間のマルチプロセッシングです— Proアカウント = アクティブなOpenCodeセッション。2つのアカウント = 2つの並列セッション。複数のGradleプロジェクトを同時に扱う人にとって、これはゲームチェンジャー。

関連記事