Deploying Your Agent
Ship your agent as an API and a web app: environment config, secrets, background jobs, and a deploy you can repeat.
An agent that only runs on your laptop is a demo. An agent with a URL, running while you sleep, serving people who aren't you, is a product. The gap between the two is smaller than it looks, but it's full of small traps: secrets baked into images, workers killed mid-run by every deploy, a Redis instance that quietly evicts your job queue, a "quick deploy" nobody can reproduce a month later.
This lesson walks you through shipping a TypeScript agent as two services from one codebase: an HTTP API that accepts work and a background worker that runs the agent. You'll validate configuration at startup, containerize both with one Dockerfile, run the whole stack locally with Docker Compose, deploy it to a platform of your choice, and wire up a CI pipeline so every deploy is repeatable. It builds directly on the architecture from the previous lesson, simplified so you can ship it today.
What you're deploying
Two processes, one codebase, one image:
- API service: accepts
POST /v1/runs, enqueues a job, returns a run ID. Serves run status. Never runs the agent itself. - Worker service: pulls jobs from the queue, runs the agent loop, stores the result.
- Redis: the job queue (via BullMQ). In this lesson it also holds results, to keep the moving parts few. For long-running production agents, add the Postgres checkpoint store from the previous lesson.
agent-service/
src/
config.ts # validated environment config
queue.ts # shared queue connection
agent.ts # your agent (from Module 5)
api.ts # HTTP service
worker.ts # background worker
Dockerfile
compose.yaml
package.json
tsconfig.json
.dockerignore
.env.exampleSet up the project:
mkdir agent-service && cd agent-service
npm init -y
npm install @anthropic-ai/sdk bullmq ioredis hono @hono/node-server zod
npm install -D typescript tsx @types/node{
"type": "module",
"scripts": {
"build": "tsc",
"dev:api": "tsx watch src/api.ts",
"dev:worker": "tsx watch src/worker.ts",
"start:api": "node dist/api.js",
"start:worker": "node dist/worker.js"
}
}{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"rootDir": "src",
"outDir": "dist",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}