Welcome to Agents Academy
Module 11 · Production · ~8 min
Deployment.
By the end of this module, your agent runs as a real service, in a container, with scoped secrets, restartable, and ready to be left alone for days at a time. The boundary between “I have an interesting script” and “I have something I trust to keep running.”
To get there, you’ll package your agent into a reproducible Docker container with scoped secrets and a sandbox. This is the foundation every later Production-tier module builds on, monitoring, kill switches, and adversarial defense all assume a containerised, least-privilege runtime.
Production tier · Reference cardHow do you deploy an LLM trading agent to production?
Package the agent into a reproducible Docker container that runs as a non-root user, inject secrets at runtime, mount one persistent volume for state, and sandbox it with least privilege; docker compose up -d on any VPS is a deployed agent. The compose file sets restart: unless-stopped, loads LIMITLESS_API_KEY, your LLM provider key (ANTHROPIC_API_KEY or OPENAI_API_KEY), and DRY_RUN=true for the first boot from .env, and mounts a data volume so state, traces, and the kill-switch flag survive restarts. Sandboxing means an outbound allowlist to api.limitless.exchange and your LLM endpoint, a read-only code mount, and dropped Linux capabilities, so a compromised prompt cannot phone home. Before scheduling the loop, run the cost arithmetic: a 15-minute loop on Claude Sonnet lands around $30–80/month in LLM spend plus a $5–15 VPS, under $100 all-in.
Deployment patterns are generic; the Limitless specifics are partly verified.
Prerequisite: deployment depends on correct auth setup; if you’re hazy on how the API key gets signed into requests, API Academy Module 03 walks through it in ~10 minutes. Optional but recommended.
Section 01
Runtime choices.
There are four practical paths to shipping an LLM-powered trading agent in 2026. They are not strictly ranked, pick based on the model you already trust, the language your tools are in, and how much operational surface you want to own.
| Runtime | Pros | Cons |
|---|---|---|
Claude Anthropic API |
First-class tool use, long context, strong instruction-following, easy to debug. | Hosted only. Rate limits on new accounts. Per-token cost higher than open models. |
OpenAI Function calling |
Battle-tested function-calling API, wide ecosystem support, cheap for the throughput. | Tool schemas less expressive than Claude’s. Occasionally aggressive on parallel tool calls. |
MCP Model Context Protocol |
Write tools once, consume from any MCP-capable client. Good for shared tool libraries. | Protocol is still maturing. Fewer production references. More moving pieces to monitor. |
Self-hosted Llama 3, Qwen, etc. |
No per-token cost, full data control, runs offline, predictable latency. | Weaker tool-use reliability, you own the GPU ops, upgrade cycles are manual. |
Most solo builders should start with Claude or OpenAI. Revisit the other two after you have a month of clean production runs on a hosted model.
Section 02
Containerise the agent.
A container gives you a reproducible runtime, easy restarts, and a clean boundary for secrets. The Dockerfile below runs the agent on a timer inside a slim base image. Use docker compose up -d on any VPS and you have a deployed agent.
How to run this
- Install Docker Desktop (or Docker Engine on Linux), then create a .env file in the project root with LIMITLESS_API_KEY, your LLM provider key (ANTHROPIC_API_KEY or OPENAI_API_KEY), and DRY_RUN=true for the first boot.
- Save the snippet as Dockerfile plus a sibling docker-compose.yml (uncomment the compose block), then run docker compose up -d --build from that folder.
- Save the snippet as Dockerfile plus a sibling docker-compose.yml (uncomment the compose block), then run docker compose up -d --build from that folder.
- Confirm with docker compose logs -f agent, you should see the schedule loop tick once, call the LLM, and log a DRY_RUN decision without placing any orders.
# Module 11: Dockerfile for a TypeScript Limitless agent
FROM node:20-slim
# Install the CLI tools the agent calls out to (Module 07 + 08)
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
&& curl -fsSL https://install.limitless.exchange/cli | sh \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile --prod
COPY . .
RUN pnpm run build
# Non-root user for defense in depth
RUN useradd -r -u 1001 agent && chown -R agent /app
USER agent
# Default command: run a strategy (built JS)
CMD ["node", "dist/strategies/cross-market-mm/run.js"]
# ---- docker-compose.yml ----
#
# services:
# agent:
# build: .
# restart: unless-stopped
# env_file: .env # LIMITLESS_API_KEY, ANTHROPIC_API_KEY, DRY_RUN, ACADEMY_DATA_DIR=/app/data, etc.
# volumes:
# - ./data:/app/data # $ACADEMY_DATA_DIR: agent.log.ndjson, kill_switch.flag, state/traces/, state/traces.db
# mem_limit: 512m
# cpus: 0.5
# Module 11: Dockerfile for a Python Limitless agent
FROM python:3.12-slim
# Install the CLI tools the agent calls out to (Module 07 + 08)
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
&& curl -fsSL https://install.limitless.exchange/cli | sh \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN pip install --no-cache-dir uv && uv sync --frozen --no-dev
COPY . .
# Non-root user for defense in depth
RUN useradd -r -u 1001 agent && chown -R agent /app
USER agent
# Default command: your agent's scheduler entrypoint
CMD ["uv", "run", "python", "-m", "my_agent"]
# ---- docker-compose.yml ----
#
# services:
# agent:
# build: .
# restart: unless-stopped
# env_file: .env # LIMITLESS_API_KEY, OPENAI_API_KEY, DRY_RUN, ACADEMY_DATA_DIR=/app/data, etc.
# volumes:
# - ./data:/app/data # $ACADEMY_DATA_DIR: agent.log.ndjson, kill_switch.flag, state/traces/, state/traces.db
# mem_limit: 512m
# cpus: 0.5
Section 03
Secrets management.
A trading agent touches three kinds of secrets: the Limitless API key, the LLM provider key, and any wallet or signer credentials. Every one of them is bearer-equivalent, if leaked, the finder can drain your account or your LLM budget. Treat them accordingly.
Do
- • Inject secrets at runtime via env vars or a secrets manager (Doppler, Infisical, AWS Secrets Manager, Vault).
- • Rotate keys quarterly and immediately on any suspected leak.
- • Scope API keys to the minimum required permissions.
- • Use a separate key for staging vs production.
Never
- • Commit .env, config.json, or any key file to git.
- • Log secrets (even in “debug” mode, it always leaks).
- • Bake secrets into a Docker image at build time.
- • Feed secrets into the LLM context. They will end up in a trace file.
The simplest workflow that satisfies all four is Doppler or Infisical injecting into the container at docker run. For scale up, move to cloud secret managers. Avoid hand-rolled solutions.
Section 04
Cost modelling.
Before you schedule the loop, do the arithmetic. Agents are notorious for burning LLM credits overnight because nobody ran the numbers. The formula is boring but necessary:
daily_cost = loops/day × LLM_calls/loop × tokens/call × $/token
+ API_requests/loop × loops/day × $/request
+ infra_monthly / 30
A realistic order of magnitude for a one-person operation running every 15 minutes on Claude Sonnet:
Loops/day
96
LLM calls/loop
3–5
Tokens/call
~2k
Monthly cost
$30–80
Add a $5–15/month VPS and you are under $100 all-in. If your agent is not earning that much in expected value, raise the loop interval or switch to a cheaper model before you go live.
Section 05
Sandbox the agent.
Your agent has an API key that can move money. Treat it like a service handling PII, principle of least privilege. The container should have access to exactly what it needs and nothing else.
Network egress allowlist
Only allow outbound traffic to api.limitless.exchange, api.anthropic.com (or your LLM provider), and your logging endpoint. Block everything else. If the agent is compromised, it cannot phone home to an attacker’s server.
Filesystem scoping
Mount the code directory read-only. Give the agent a single writable volume for state (/data/state) and logs (/data/logs). Use tmpfs for scratch. No write access to the binary or config.
Process isolation
Run as a non-root user (you already do this from Section 02). Drop all Linux capabilities with --cap-drop=ALL. Consider --security-opt=no-new-privileges. If you are on a shared host, use a separate container per agent.
Separate credentials per agent
If you run multiple agents, give each its own Limitless API key with scoped permissions. A research agent should have a read-only key. A trading agent gets a key with order permissions. Never share keys across agents.
Anti-pattern: prompt-only authorization
“Only place orders if the user has approved” in the system prompt is not authorization, it is a suggestion that the model can ignore or be tricked into bypassing. Authorization must be enforced in code: the tool layer checks permissions, not the prompt.
Agent deployment: what people ask
Each answer also ships invisibly as schema.org FAQ data for search engines and AI assistants. Tap a question to expand.
-
Which LLM runtime should a trading agent use?
Four practical paths: Claude (first-class tool use, long context, strong instruction-following, but hosted only with higher per-token cost), OpenAI (battle-tested function calling, cheap for the throughput), MCP (write tools once, consume from any MCP-capable client, but the protocol is still maturing), and self-hosted models like Llama 3 or Qwen (no per-token cost, full data control, weaker tool-use reliability). Most solo builders should start with Claude or OpenAI and revisit the others after a month of clean production runs. -
How much does it cost to run an LLM trading agent?
Run the formula before you schedule the loop:daily_cost = loops/day × LLM_calls/loop × tokens/call × $/token, plus API requests and infra/30. A realistic one-person setup running every 15 minutes on Claude Sonnet: 96 loops/day, 3–5 LLM calls per loop, ~2k tokens per call, $30–80/month, plus a $5–15/month VPS, under $100 all-in. If the agent is not earning that in expected value, raise the loop interval or switch to a cheaper model. -
How should a trading agent’s secrets be handled?
Inject them at runtime via env vars or a secrets manager (Doppler, Infisical, AWS Secrets Manager, Vault), rotate quarterly and immediately on any suspected leak, scope keys to minimum permissions, and keep separate keys for staging and production. Never commit.envor key files to git, never log secrets (debug mode always leaks), never bake them into a Docker image at build time, and never feed them into the LLM context, they will end up in a trace file. -
How do you sandbox a trading agent?
Least privilege on four axes. Network: an egress allowlist toapi.limitless.exchange, your LLM provider (e.g.api.anthropic.com), and your logging endpoint, so a compromised agent cannot phone home. Filesystem: code mounted read-only, one writable volume for state and logs,tmpfsfor scratch. Process: non-root user,--cap-drop=ALL, consider--security-opt=no-new-privileges. Credentials: a separate scoped Limitless API key per agent, read-only for research agents, order permissions only for the trader. -
What counts as a real deploy gate for an agent?
Enforceable checks, not “tests pass on my machine”: the suite green in CI, risk caps verified in code by a pre-deploy script that fails ifmaxSizeis missing, the kill switch tested live by touching$ACADEMY_DATA_DIR/kill_switch.flagand watching the loop refuse to act, trace redaction confirmed, and a pinned run-book. Each item is a green check or a hard stop, no waivers. Prompt-only authorization is a suggestion, not a control; the tool layer checks permissions.
Module checklist
Five quick confirmations.
Tick each item once you’ve actually done it. The Continue button unlocks at 5/5.
I picked a runtime (Claude, OpenAI, MCP, or self-hosted) and can justify the choice
My agent runs inside a Docker container with a non-root user
State volumes are mounted so position state and traces survive restarts
No secrets are committed to git; I verified with git log -p
I wrote down a monthly cost estimate using the formula above
Module 11 complete
Shipped, not just running.
Your agent is no longer a script you babysit. It runs in a container with scoped secrets, restarts itself when it crashes, and lives behind the same boundaries every production service does, you can close your terminal and walk away.
Concretely, your agent is no longer a script on your laptop, it is a containerised service with a budget, scoped secrets, and a sandbox.
A reproducible Dockerfile + docker-compose.yml pair that runs the agent as a non-root user, mounts persistent state and kill-switch volumes, and restarts unless-stopped.
A concrete monthly cost estimate built from the loops/day × LLM_calls/loop × tokens/call × $/token formula, you know what this agent will burn before it ever sees live size.
A hardened runtime: secrets injected from a manager (Doppler / Infisical / Vault), outbound allowlist to the API + LLM endpoints, filesystem scoped to /data/state, and all Linux capabilities dropped.
Next up: wiring observability into the loop, traces, metrics, and structured logs so you can tell a healthy agent from a runaway one at a glance.
Complete the checklist above to unlock