tiempo de lectura : 14 minutes

Dos suscripciones Pro, una sola máquina, una sola tarjeta bancaria y cero conflictos de red. ¿Cómo Docker me permitió duplicar mi capacidad de inferencia en la nube sin comprar una segunda PC.

Introducción

Utilizo Ollama Pro desde varios meses para alimentar mis sesiones OpenCode con modelos en la nube. El truco es que incluso con una suscripción Pro, se llega rápidamente al rate limiting cuando se lanzan varios agentes en paralelo. La solución obvia: una segunda suscripción.

Pero ahí, es el drama.

Ollama identifica cada máquina mediante una clave SSH única — su famosa Device Key. Dos instancias en el mismo SO compartirían la misma identidad, y es imposible vincular dos cuentas Pro al mismo dispositivo. Y, como te imaginas, no iba a comprar otro portátil solo para eso.

La solución: engañar. Hacer creer a Ollama que se ejecuta en dos máquinas diferentes, cuando en realidad comparten la misma CPU, la misma RAM y la misma conexión de red. Docker nos ofrecerá una burbuja de aislamiento perfecto.

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 "Ollama Instancia A (Nativa)" as Native {
    database "Identidad
^^^^^
 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 "Ollama Instancia A (Nativa)" as Native {
    database "Identidad
/usr/share/ollama/.ollama/id_ed25519" as KeyA
    portin "API
:11434" as PortA
  }

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

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

KeyA --> AccountA : "Clave SSH A"
KeyB --> AccountB : "Clave SSH B"
PortA --> AccountA : "Consultas A"
PortB --> AccountB : "Consultas B"

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

¿Por qué dos veces lo mismo?

Antes de que me llames enfermo mental, déjame explicarte el caso de uso.

Con una sola suscripción Pro, puedo lanzar un modelo como`deepseek-v4-pro:cloud`dans una sesión OpenCode. El problema surge cuando quiero dos sesiones simultáneas. Los límites de rate limiting hacen que la segunda sesión se ralentice o sea rechazada directamente.

Con dos suscripciones Pro independientes :

  • Sesión OpenCode 1 → Cuenta Pro A (localhost:11434)

  • Sesión OpenCode 2 → Cuenta Pro B`localhost:11435`)

Cada sesión tiene su propia cuota, su propio contexto, y no interfiere con la otra. Es multiprocesamiento humano.

Dos suscripciones Pro = dos correos electrónicos diferentes. La misma tarjeta bancaria funciona — el sistema de pago de Ollama no bloquea las suscripciones múltiples desde el mismo medio de pago. Lo he verificado.

El corazón del problema: La Device Key

Cuando instalas Ollama, se genera un par de claves SSH ed25519 en el directorio de identidad :

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

Esta clave se sube a los servidores de Ollama durante el`ollama signin`. Es ella quien dice « esta máquina pertenece a esa cuenta Pro ». Si sus dos instancias comparten el mismo archivo`id_ed25519`, ellas comparten la misma identidad. Fin del juego.

El truco: dar a nuestra segunda instancia su propio directorio de identidad, aislado en un volumen Docker.

Preparación — Paso a Paso

prerrequisitos

  • Una instalación nativa de Ollama funcional (script oficial`curl | sh`)

  • Docker instalado y funcional

  • Portainer o docker-compose para el despliegue

  • Dos cuentas Ollama con dos correos electrónicos distintos

He utilizado la versión`0.20.2`— aquella proporcionada por el script oficial y la imagen Docker correspondiente.

Paso 1: Crear el Volumen

Un simple directorio en el host servirá como volumen persistente para la identidad de la instancia B :

mkdir -p ~/ollama-b-data

Este directorio se montará en el contenedor Docker como`/root/.ollama`, donde Ollama almacena sus claves de identidad, su historial y sus modelos.

Paso 2: Lanzar el contenedor 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

Lo que está pasando aquí:

  • El puerto11435del host está mapeado al11434interno del contenedor. Así, la instancia Docker escucha en`:11435`sin conflicto con la instancia nativa que ocupa`:11434`.

  • El volumen`~/ollama-b-data`está montado sobre`/root/.ollama`— aquí es donde se almacenará la identidad SSH.

  • `OLLAMA_HOST=0.0.0.0`permite al contenedor aceptar conexiones externas.

He desplegado esta pila mediante Portainer, pero un simple`docker compose up -d`funciona también bien.

Paso 3 : Obtener la Clave Pública

Al estar el contenedor vacío en el primer arranque, Ollama genera automáticamente una nueva pareja de claves SSH en el volumen. Se recupera la clave pública :

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

Compruebo que esta clave es diferente de la instancia 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)

Dos llaves distintas, dos identidades separadas. El truco está hecho.

Si su contenedor se reinicia, reutiliza las claves presentes en el volumen. La identidad es persistente. No perderá la asociación con la cuenta Pro.

Paso 4: Registrar la clave en Ollama.com

Dirección https://ollama.com/settings/keys → Añadir clave SSH. Se pega la clave pública de la instancia Docker y se valida.

Luego, se vincula esta identidad a la cuenta Pro B :

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

Se abre el navegador, nos conectamos con el correo electrónico de la cuenta B, y el token se asocia a la clave SSH del contenedor. Comprobamos que todo esté OK:

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

Paso 5 : Probar con un Modelo Pequeño Gratuito

Antes de lanzar el precio de una suscripción Pro, quiero estar seguro de que el tubo funcione. Hago un pull de un modelo local pequeño y gratuito para validar la conectividad :

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

El puerto`11435`responde, el modelo está servido. La instancia B está viva.

Una vez tranquilo, paso al pull del verdadero modelo cloud Pro:

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

344 bytes para el manifiesto de un modelo en la nube — normal, la inferencia se realiza del lado del servidor, no localmente. Y aquí está la prueba definitiva:

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

Hola también para ti, instancia B.

La Trampa de la API `/v1/models

He perdido 20 minutos en un detalle tonto. Cuando he configurado el proveedor`ollama-b`en OpenCode, nada aparecía en el selector de modelos. Nada. Nada de nada.

¿La razón? L’API`/v1/models`de la instancia B devolvía`{"object":"list","data":null}`en lugar de`{"object":"list","data":[]}`quand ningún modelo estaba siendo tirado. El valor`null`en OpenCode, provocaba un fallo en el análisis, que no mostraba el proveedor.

La solución: declarar los modelos explicitamente en la configuración de OpenCode en lugar de depender del descubrimiento dinámico.

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

Con esta declaración explícita, OpenCode ve inmediatamente al provider B y sus modelos. Un reinicio de sesión, y el selector`/models`muestra las dos instancias una al lado de la otra.

Si no ves tu proveedor personalizado en`/models`, no pierdas tres horas reiniciando tu terminal. Declara los modelos manualmente en`opencode.json`— esto resuelve el problema instantáneamente.

Resultado : Dos Sesiones, Dos Cuentas, Cero Conflicto

Al final, puedo lanzar dos sesiones OpenCode simultáneamente :

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 sesión tiene su propio quota, su propio límite de tasa, y no se pisotean los pies. La misma máquina, la misma tarjeta azul, dos correos electrónicos diferentes.

¿Y lo mejor? El contenedor Docker está en`restart: always`. Sobrevive a los reinicios del sistema sin intervención manual.

Lecciones Aprendidas

  1. Docker aísla todo, incluso la identidad— Un simple bind mount de volumen es suficiente para dar a un contenedor su propio conjunto de claves SSH, haciéndolo indistinguible de una máquina física diferente a los ojos de Ollama.

  2. Dos correos electrónicos, misma CB— Ollama no bloque las suscripciones múltiples desde el mismo medio de pago. Solo el correo electrónico debe ser distinto.

  3. Probar gratis 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` con data: null rompe OpenCode— Si configuras un proveedor personalizado con`"models": {}`, OpenCode intenta descubrir los modelos a través de la API. Si la API responde`data: null`, el proveedor no aparece. Declara los modelos explícitamente.

  5. Dos cuentas, es multi-procesamiento humano— Una cuenta Pro = una sesión OpenCode activa. Dos cuentas = dos sesiones paralelas. Para alguien que está manejando varios proyectos Gradle simultáneamente, es un cambio de juego.

Articles connexes