tempo de leitura : 14 minutes

Duas assinaturas Pro, uma única máquina, um único cartão bancário, e nenhum conflito de rede. Como o Docker me permitiu dobrar minha capacidade de inferência na nuvem sem comprar um segundo PC.

Introdução

Estou usando o Ollama Pro há vários meses para alimentar minhas sessões OpenCode com modelos de nuvem. O problema é que, mesmo com uma assinatura Pro, ficamos rapidamente limitados pelo rate limiting quando iniciamos vários agentes em paralelo. A solução óbvia: uma segunda assinatura.

Mas aí, é o drama.

Ollama identifica cada máquina por uma chave SSH única — a sua famosa Device Key. Duas instâncias no mesmo SO compartilhariam a mesma identidade, e seria impossível vincular duas contas Pro ao mesmo device. E como você já deve imaginar, eu não ia comprar um segundo laptop só por isso.

A solução: trapacear. Fazer o Ollama acreditar que está sendo executado em duas máquinas diferentes, embora compartilhem o mesmo CPU, a mesma RAM e a mesma conexão de rede. Docker nos oferecerá uma bolha de isolamento perfeito.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 10) ]

@startuml




...
... ( skipping 130 lines )
...
skinparam StereotypeI {
  BackgroundColor white
  BorderColor black
}
skinparam StereotypeN {
  BackgroundColor white
  BorderColor black
}
skinparam UseCaseStereoType {
  FontColor black
  FontName Verdana
}
skinparam BoxPadding 10
skinparam DefaultFontSize 12

left to right direction

node "Máquina Física" {
  frame "Instância A do Ollama (Nativa)" as Native {
    database "Identity
^^^^^
 Syntax Error? (Assumed diagram type: class)

@startuml
!theme plain
skinparam BoxPadding 10
skinparam DefaultFontSize 12

left to right direction

node "Máquina Física" {
  frame "Instância A do Ollama (Nativa)" as Native {
    database "Identity
/usr/share/ollama/.ollama/id_ed25519" as KeyA
    portin "API
:11434" as PortA
  }

  frame "Ollama Instance B (Docker)" as Docker {
    database "Identidade
~/ollama-b-data/id_ed25519" as KeyB
    portin "API
:11435" as PortB
  }
}

cloud "Ollama Cloud" {
  actor "Conta Pro A\n(email 1)" as AccountA
  actor "Conta Pro B\n(e-mail 2)" as AccountB
}

KeyA --> AccountA : "Chave SSH A"
KeyB --> AccountB : "Chave SSH B"
PortA --> AccountA : "Requisições A"
PortB --> AccountB : "Consultas B"

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

Por que fazer a mesma coisa duas vezes?

Antes de me chamar de doente mental, deixe-me explicar o caso de uso para você.

Com uma única assinatura Pro, posso lançar um modelo como`deepseek-v4-pro:cloud`dentro de uma sessão OpenCode. O problema surge quando eu quero duas sessões simultâneas. As cotas de rate limiting fazem com que a segunda sessão trave ou seja pura e simplesmente rejeitada.

Com duas assinaturas Pro independentes:

  • Sessão OpenCode 1 → Conta Pro A`localhost:11434`)

  • Session OpenCode 2 → Conta Pro B`localhost:11435`)

Cada sessão tem sua própria cota, seu próprio contexto, e não incomoda a outra. É multi-processamento humano.

Duas assinaturas Pro = dois e‑mails diferentes. O mesmo cartão de crédito funciona — o sistema de pagamento da Ollama não bloqueia assinaturas múltiplas a partir do mesmo meio de pagamento. Verifiquei.

O Coração do Problema : A Device Key

Quando você instala o Ollama, um par de chaves SSH ed25519 é gerado no diretório de identidade:

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

Esta chave é feita upload para os servidores da Ollama durante o`ollama signin`. Ela é quem diz « esta máquina pertence a tal conta Pro ». Se suas duas instâncias compartilharem o mesmo arquivo`id_ed25519`, elas compartilham a mesma identidade. Fim do jogo.

O expediente : dar à nossa segunda instância seu próprio diretório de identidade, isolado em um volume Docker.

Colocação — Passo a Passo

Pré-requisito

  • Uma instalação nativa do Ollama funcional (script oficial`curl | sh`)

  • Docker instalado e funcional

  • Portainer ou docker-compose para a implantação

  • Duas contas Ollama com dois e-mails distintos

Eu usei a versão`0.20.2`— a fornecida pelo script oficial e a imagem Docker correspondente.

Etapa 1: Criar o Volume

Um diretório simples no host servirá como volume persistente para a identidade da instância B:

mkdir -p ~/ollama-b-data

Esta pasta será montada no contêiner Docker como`/root/.ollama`, onde o Ollama armazena suas chaves de identidade, seu histórico e seus modelos.

Passo 2: Iniciar o contêiner 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

O que se passa aqui:

  • O porto11435do host é mapeado para o11434interna do contêiner. Assim, a instância Docker ouve em`:11435`sem conflito com a instância nativa que ocupa`:11434`.

  • O volume`~/ollama-b-data`está montado sobre`/root/.ollama`— é aqui que a identidade SSH será armazenada.

  • `OLLAMA_HOST=0.0.0.0`permite ao contêiner aceitar conexões externas.

Eu implementei essa stack via Portainer, mas um simples`docker compose up -d`funciona tão bem quanto.

Passo 3: Recuperar a Chave Pública

Como o container está vazio na primeira inicialização, Ollama gera automaticamente um novo par de chaves SSH no volume. Recuperamos a chave pública:

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

Eu verifico que essa chave é diferente daquela da instância nativa :

# 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)

Duas chaves distintas, duas identidades separadas. O truque foi feito.

Se o seu contêiner reiniciar, ele reutiliza as chaves presentes no volume. A identidade é persistente. Você não perderá a associação com a conta Pro.

Passo 4: Registrar a Chave no Ollama.com

Acesse https://ollama.com/settings/keys → Adicionar Chave SSH. Cole a chave pública da instância Docker e valide.

Em seguida, vincula-se esta identidade à conta Pro B :

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

O navegador se abre, conectamo-nos com o e-mail da conta B e o token é associado à chave SSH do contêiner. Verificamos que tudo está OK :

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

Passo 5: Testar com um modelo pequeno gratuito

Antes de mencionar o preço de uma assinatura Pro, quero ter certeza de que o tubo funciona. Eu faço um pull de um pequeno modelo local e gratuito para validar a conectividade:

$ 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",...}]}

O porto`11435`responde, o modelo está servido. A instância B está viva.

Depois de ficar tranquilo, passo para o pull do modelo cloud Pro verdadeiro :

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

344 bytes para o manifesto de um modelo cloud — normal, a inferência é feita do lado do servidor, não localmente. Eis o teste definitivo :

$ 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 }
}

Olá também a ti, instance B.

A armadilha da API `/v1/models

Perdi 20 minutos em um detalhe bobo. Quando eu configurei o provedor`ollama-b`no OpenCode, nada apareceu no seletor de modelos. Nada. De forma alguma.

A razão? L’API`/v1/models`da instância B retornou`{"object":"list","data":null}`em vez de`{"object":"list","data":[]}`quand nenhum modelo estava sendo puxado. O valor`null`fazia o parsing travar no lado OpenCode, que não exibia o provider.

A solução: declarar os modelos explícitamente na configuração OpenCode em vez de contar com a descoberta dinâmica.

~/.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)" }
      }
    }
  }
}

Com esta declaração explícita, o OpenCode vê imediatamente o provider B e seus modelos. Um reinício de sessão, e o seletor`/models`mostra as duas instâncias lado a lado.

Se você não vê seu provider custom em`/models`, não perca três horas a reiniciar seu terminal. Declare os modelos manualmente em`opencode.json`— isso resolve o problema instantaneamente.

Resultado: Duas Sessões, Duas Contas, Zero Conflito

Finalmente, posso lançar duas sessões OpenCode simultaneamente:

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

Cada sessão tem sua própria cota, seu próprio rate limit, e não se pisam nos pés. Mesmo máquina, mesmo cartão azul, dois e-mails diferentes.

E o melhor? O contêiner Docker está em`restart: always`. Ele sobrevive às reinicializações do sistema sem intervenção manual.

Lições Aprendidas

  1. Docker isola tudo, mesmo a identidade— Um simples bind mount de volume é suficiente para dar a um contêiner seu próprio conjunto de chaves SSH, tornando-o indistinguível de uma máquina física diferente aos olhos do Ollama.

  2. Dois e-mails, mesmo CB— Ollama não bloque as assinaturas múltiplas desde o mesmo meio de pagamento. Só o email deve ser distinto.

  3. Testar grátis antes de pagar — 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` com data: null quebra OpenCode— Se você configurar um provider custom com`"models": {}`, OpenCode tenta descobrir os modelos via a API. Se a API responde`data: null`, o provedor não aparece. Declare os modelos explicitamente.

  5. Duas contas, isso é multiprocessamento humano— Uma conta Pro = uma sessão OpenCode ativa. Duas contas = duas sessões paralelas. Para alguém que está malabarizando entre vários projetos Gradle simultaneamente, isso é um game changer.

Articles connexes