Deploy a Worker with Docker
A worker built with the Allora Python SDK is a single Python process, so containerizing it is a plain Python Dockerfile plus two operational details:
- The wallet key must reach the container without being baked into the image — the worker's interactive mnemonic prompt cannot run in a detached container.
- A restart policy keeps the worker running after crashes and host reboots.
Coming from the legacy config.json-based worker stack? That stack is deprecated — follow Migrate from the Offchain Node first, then return here to containerize the result.
Goal
Run your Python SDK worker as a detached Docker container that restarts automatically, with its wallet key mounted read-only from the host.
Prerequisites
- Docker Engine (opens in a new tab) (or Docker Desktop)
- A worker script — this page uses the minimal
worker.pyfrom the Python SDK guide; any worker built onAlloraWorkerworks the same way - An Allora API key — free at developer.allora.network (opens in a new tab); on testnet, the worker uses it to request ALLO gas from the faucet automatically
Steps
1. Lay out the project
allora-worker/
├── worker.py # your worker
├── requirements.txt # Python dependencies
├── Dockerfile
├── .dockerignore
└── .allora_key # wallet mnemonic -- created in step 2, never copied into the imageworker.py — the minimal worker (replace the body of run_model with your model, and COPY any extra model files in the Dockerfile below):
import asyncio
import os
from allora_sdk import AlloraNetworkConfig, AlloraWorker
async def run_model(nonce: int) -> float:
# Your ML model's prediction logic goes here
return 123.45
async def main():
worker = AlloraWorker.inferer(
run=run_model,
topic_id=69,
network=AlloraNetworkConfig.testnet(),
api_key=os.environ.get("ALLORA_API_KEY"),
)
async for result in worker.run():
if isinstance(result, Exception):
print(f"Inference worker error: {result}")
else:
print(f"Prediction submitted to Allora: {result.submission}")
asyncio.run(main())requirements.txt — the SDK plus whatever your model imports:
allora_sdk2. Create the wallet key on the host
Inside a container the worker cannot prompt you for a mnemonic, so create the .allora_key file on the host first. Either run the worker once locally (press Enter at the Mnemonic: prompt to generate an identity — see the SDK guide), or write an existing mnemonic to the file yourself:
( umask 077; printf '%s\n' "$ALLORA_WALLET_MNEMONIC" > .allora_key ).allora_key is your worker's identity and funds. Keep it out of the image and out of version control — add it to both .dockerignore and .gitignore, and keep a backup.
.dockerignore:
.allora_key
.git3. Write the Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY worker.py .
# Stream logs straight to `docker logs` instead of buffering them
ENV PYTHONUNBUFFERED=1
CMD ["python", "worker.py"]The SDK supports Python 3.10–3.13, so any python:3.10-slim through python:3.13-slim base works. If your model has heavier dependencies (for example scikit-learn from the SDK guide's price model), add them to requirements.txt and COPY the model files next to worker.py.
4. Build the image
docker build -t allora-worker .5. Run it with the key mounted and a restart policy
export ALLORA_API_KEY="<your key from developer.allora.network>"
docker run -d \
--name allora-worker \
--restart unless-stopped \
-e ALLORA_API_KEY \
-v "$PWD/.allora_key:/app/.allora_key:ro" \
allora-worker-v "$PWD/.allora_key:/app/.allora_key:ro"mounts the mnemonic file read-only at the path the worker checks by default (.allora_keyin its working directory,/app). The key never enters the image, so the image is safe to push to a registry.--restart unless-stoppedrestarts the container after a crash and when the Docker daemon comes back up (e.g. after a host reboot), but respects an explicitdocker stop. Use--restart alwaysif the worker should come back even after being stopped manually, or--restart on-failureto restart only on non-zero exits.-e ALLORA_API_KEYforwards the variable from your shell without writing the value into the command line or the image.
Prefer to pass the mnemonic as an environment variable instead of a file mount? Configure the wallet explicitly in worker.py — wallet=AlloraWalletConfig(mnemonic=os.environ["ALLORA_WALLET_MNEMONIC"]) as shown in the SDK guide — and run with -e ALLORA_WALLET_MNEMONIC. Note that container environment variables are visible to anyone who can run docker inspect on the host; the read-only file mount is the safer default.
6. (Optional) Run it with Docker Compose
docker-compose.yml:
services:
worker:
build: .
container_name: allora-worker
restart: unless-stopped
environment:
- ALLORA_API_KEY=${ALLORA_API_KEY}
volumes:
- ./.allora_key:/app/.allora_key:rodocker compose up -d --buildVerify
-
docker psshows the container with a status ofUp .... -
The restart policy is active:
docker inspect -f '{{ .HostConfig.RestartPolicy.Name }}' allora-workerprints
unless-stopped. -
docker logs -f allora-workershows the same lifecycle as a local run — the wallet address and balance at startup (plus a faucet top-up on a fresh testnet wallet), then, each time a submission window opens, lines like:🚀 Worker submission window opened (topic 69, nonce <block height>, height <block height>) 👉 Found new nonce <block height> for topic 69, submitting... ✅ Successfully submitted: topic=69 nonce=<block height> - Transaction hash: <tx hash> Prediction submitted to Allora: <your prediction> -
Open testnet.explorer.allora.network/topics/69 (opens in a new tab) and look for your worker's
allo...address among the topic's workers. For dashboards and on-chain score queries, see Monitor a Worker.
Kubernetes
The same container runs on Kubernetes with three adjustments:
- One replica per wallet. Run the worker as a Deployment with
replicas: 1. Transactions from one account must be submitted in strict sequence order, so two pods signing with the same key will conflict. To scale across topics, run one Deployment (and one wallet) per topic. - Key from a Secret. Store the mnemonic in a Kubernetes Secret and mount it read-only at
/app/.allora_key(or expose it as an environment variable consumed byAlloraWalletConfig, as above). Do not bake it into the image. - Restarts come built in. A Deployment's default
restartPolicy: Alwaysreplaces the Docker restart policy; nothing extra is needed for crash recovery.
docker stop, Compose shutdowns, and Kubernetes pod termination all deliver SIGTERM, which the worker treats as a graceful shutdown.
Troubleshoot
- Container exits immediately or restart-loops — read
docker logs allora-worker. The most common cause is a missing key mount: without/app/.allora_key, the worker falls back to its interactive mnemonic prompt, which fails in a detached container. Check the mount path and that.allora_keyexists on the host. - No log output — Python buffers stdout by default when it is not a TTY. The Dockerfile above sets
PYTHONUNBUFFERED=1; if you wrote your own, add it (or runpython -u worker.py). Too many faucet requests— the testnet faucet is rate-limited. Send ALLO to the worker's address from another wallet, or request funds manually at faucet.testnet.allora.network (opens in a new tab), then restart the container.- gRPC
StatusCode.UNIMPLEMENTEDwithunknown service emissions.vN.QueryService— the image holds an SDK release older than the deployed network. Rebuild without cache to pick up the latest release:docker build --no-cache -t allora-worker .. For reproducible deploys, pin the version inrequirements.txt(e.g.allora_sdk==1.0.6) and bump it deliberately. - Worker runs but never submits — submission windows only open once per topic epoch, so quiet stretches are normal. Confirm the worker is registered and scored via Monitor a Worker.
Next
- Watch your worker: monitor a worker — dashboards, logs, and EMA scores
- Full worker configuration — wallets, networks, fee tiers: build a worker with the Python SDK
- Pick a topic to serve: existing topics