Stack Two Ollama Pro Subscriptions on the Same Machine with Docker
Published on 08 May 2026
Two Pro subscriptions, a single machine, a single bank card, and zero network conflict. How Docker allowed me to double my cloud inference capacity without buying a second PC.
Introduction
I’ve been using Ollama Pro for several months to power my OpenCode sessions with cloud models. The thing is, even with a Pro subscription, you quickly hit rate limiting when you launch several agents in parallel. The obvious solution: a second subscription.
But there, it’s the drama.
Ollama identifies each machine by a unique SSH key — its famous Device Key. Two instances on the same OS would share the same identity, and it would be impossible to link two Pro accounts to the same device. And as you might have guessed, I wasn’t going to buy a second laptop just for that.
The solution: cheat. Make Ollama believe it’s running on two different machines, when they actually share the same CPU, the same RAM, and the same network connection. Docker will give us a perfect isolation bubble.
@startuml
!theme plain
skinparam BoxPadding 10
skinparam DefaultFontSize 12
left to right direction
node "Physical Machine" {
frame "Ollama Instance A (Native)" as Native {
database "Identity\n/usr/share/ollama/.ollama/id_ed25519" as KeyA
portin "API\n:11434" as PortA
}
frame "Ollama Instance B (Docker)" as Docker {
database "Identity\n~/ollama-b-data/id_ed25519" as KeyB
portin "API\n:11435" as PortB
}
}
cloud "Ollama Cloud" {
actor "Pro Account A\n(email 1)" as AccountA
actor "Pro Account B\n(email 2)" as AccountB
}
KeyA --> AccountA : "SSH Key A"
KeyB --> AccountB : "SSH Key B"
PortA --> AccountA : "Requests A"
PortB --> AccountB : "B Requests"
note bottom of Docker
Conteneur isolé : identité SSH distincte,
port réseau distinct, volume persistant
end note
@enduml
Why two times the same thing?
Before calling me mentally ill, let me explain the use case.
With a single Pro subscription, I can launch a model like`deepseek-v4-pro:cloud`in an OpenCode session. The problem arises when I want two simultaneous sessions. The rate‑limiting quotas cause the second session to lag or be outright rejected.
With two independent Pro subscriptions :
-
Session OpenCode 1 → Pro Account A`localhost:11434`)
-
Session OpenCode 2 → Account Pro B`localhost:11435`)
Each session has its own quota, its own context, and does not interfere with the other. It’s human multi-processing.
|
Two Pro subscriptions = two different emails. The same credit card works — Ollama’s payment system does not block multiple subscriptions from the same payment method. I checked. |
The Heart of the Problem: The Device Key
When you install Ollama, an ed25519 SSH key pair is generated in the identity directory :
$ cat /usr/share/ollama/.ollama/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...
This key is uploaded to Ollama’s servers during the`ollama signin`. It is she who says 'this machine belongs to a Pro account'. If your two instances share the same file`id_ed25519`, they share the same identity. Game over.
The trick: give our second instance its own identity directory, isolated in a Docker volume.
Setup — Step by Step
Prerequisite
-
A functional native Ollama installation (official script`curl | sh`)
-
Docker installed and functional
-
Portainer or docker-compose for deployment
-
Two Ollama accounts with two distinct emails
I have used the version`0.20.2`— that provided by the official script and the corresponding Docker image.
Step 1: Create the Volume
A simple directory on the host will serve as a persistent volume for the identity of instance B:
mkdir -p ~/ollama-b-data
This folder will be mounted in the Docker container as`/root/.ollama`, where Ollama stores its identity keys, its history, and its models.
Step 2: Run the Docker Container
# 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
What is happening here:
-
The port11435of the host is mapped onto the11434internal to the container. Thus, the Docker instance listens on`:11435`without conflict with the native instance that squats`:11434`.
-
The volume`~/ollama-b-data`is mounted on`/root/.ollama`— this is where the SSH identity will be stored.
-
`OLLAMA_HOST=0.0.0.0`allows the container to accept external connections.
I have deployed this stack via Portainer, but a simple`docker compose up -d`works just as well.
Step 3: Retrieve the Public Key
Since the container is empty on first startup, Ollama automatically generates a new SSH key pair in the volume. We retrieve the public key:
$ docker exec ollama-instance-b cat /root/.ollama/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDDQ+dvnfmuo49q5O8LOlvgZ39SKORFw47ry9k4H2jPc
I check that this key is different from that of the native instance:
# 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)
Two distinct keys, two separate identities. The trick is done.
|
If your container restarts, it reuses the keys present in the volume. The identity is persistent. You will not lose the association with the Pro account. |
Step 4 : Save the Key on Ollama.com
Go to https://ollama.com/settings/keys → Add SSH Key. Paste the public key of the Docker instance and confirm.
Then, we link this identity to the Pro B account:
$ docker exec -it ollama-instance-b ollama signin
The browser opens, we log in with account B’s email, and the token is associated with the container’s SSH key. We check that everything is OK:
$ docker exec -it ollama-instance-b ollama signin
User: cherolivpro
Step 5: Test with a Small Free Model
Before I throw out the price of a Pro subscription, I want to be sure the pipeline works. I pull a small local free model to validate the connectivity:
$ 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",...}]}
The port`11435`It replies, the model is served. Instance B is alive.
Once reassured, I switch to the pull of the true cloud Pro model:
$ docker exec ollama-instance-b ollama pull deepseek-v4-pro:cloud
pulling manifest
pulling 31c3059e137e: 100% ▕██████████████████▏ 344 B
success
344 bytes for the manifest of a cloud model — normal, the inference is done server-side, not locally. And here is the ultimate test:
$ 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 }
}
Hello to you too, instance B.
The Trap of the API `/v1/models
I lost 20 minutes on a stupid detail. When I configured the provider`ollama-b`In OpenCode, nothing appeared in the model selector. Nothing. Nada.
The reason? The API`/v1/models`of instance B was returning`{"object":"list","data":null}`instead of`{"object":"list","data":[]}`when no model was being pulled. The value`null`was causing the parsing to crash on the OpenCode side, which did not display the provider.
The solution: declare the models explicitly in the OpenCode configuration rather than relying on dynamic discovery.
{
"$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)" }
}
}
}
}
With this explicit declaration, OpenCode immediately sees provider B and its models. A session restart, and the selector`/models`displays the two instances side by side.
|
If you don’t see your custom provider in`/models`, don’t waste three hours restarting your terminal. Declare the models manually in`opencode.json`— it solves the problem instantly. |
Result: Two Sessions, Two Accounts, Zero Conflict
In the end, I can run two OpenCode sessions simultaneously:
Session 1 → /models → Ollama (local) → deepseek-v4-pro:cloud → Compte A
Session 2 → /models → Ollama Instance B (Docker) → deepseek-v4-pro:cloud → Compte B
Each session has its own quota, its own rate limit, and they don’t step on each other’s toes. Same machine, same credit card, two different emails.
And the best? The Docker container is`restart: always`. It survives system reboots without manual intervention.
Lessons Learned
-
Docker isolates everything, even identity— A simple volume bind mount is enough to give a container its own set of SSH keys, making it indistinguishable from a different physical machine to Ollama.
-
Two emails, same CB— Ollama does not block multiple subscriptions from the same payment method. Only the email must be distinct.
-
Test for free before paying — 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. -
/v1/models` with
data: nullbreaks OpenCode— If you set up a custom provider with`"models": {}`, OpenCode attempts to discover the models via the API. If the API responds`data: null`, the provider does not appear. Declare the models explicitly. -
Two accounts, that’s human multi-processing— One Pro account = an active OpenCode session. Two accounts = two parallel sessions. For someone juggling multiple Gradle projects simultaneously, that’s a game changer.
To go further
Article published on 2026-05-08