Each service repo ships its own k8s/ directory with kustomized manifests. You apply them in order, set the secrets, and the cluster comes up.
Prerequisites
- Kubernetes 1.27+ (k3s 1.29+ tested as the reference).
- An ingress controller (nginx, Traefik, or k3s built-in).
- A Postgres 16 instance with
pgvector extension. Either bundled (apply agentflow-postgres/k8s/) or external (managed RDS / Neon).
- DNS for at least three subdomains:
api., app., and your bot landing (bot. or root).
- TLS via cert-manager or external certs.
Apply order
Namespace and secrets
kubectl create namespace agentflow
kubectl -n agentflow apply -f secrets/ # see env-variables guide
Postgres
kubectl -n agentflow apply -k agentflow-postgres/k8s/
Wait for the StatefulSet to become Ready. Run the migrations from agentflow-api:kubectl -n agentflow exec deploy/agentflow-api -- npm run migrate
API
kubectl -n agentflow apply -k agentflow-api/k8s/
Claude OAuth proxy
kubectl -n agentflow apply -k claude-oauth-proxy/k8s/
Agents and runtime
kubectl -n agentflow apply -k agentflow-agents/k8s/
kubectl -n agentflow apply -k agentflow-runtime/k8s/
Bot
kubectl -n agentflow apply -k agentflow-bot/k8s/
Ingress
Configure ingress to route:| Host | Backend |
|---|
api.<your-domain> | service/agentflow-api:3000 |
app.<your-domain> | service/agentflow-web:80 |
Then point DNS at the ingress IP.
Health and readiness
Each service exposes:
GET /health — liveness
GET /ready — readiness
Wire these into Kubernetes probes (the manifests do this by default).
Scaling
| Service | Default replicas | Scaling driver |
|---|
agentflow-api | 2 | Request rate; HPA on CPU |
agentflow-agents | 2 | Active sessions; HPA on memory |
agentflow-runtime | dynamic | Spawned per session, killed at end |
claude-oauth-proxy | 2 | Stateless; HPA on CPU |
agentflow-bot | 1 | Singleton — Telegram polling does not multi-instance well |
Storage
Provision a PersistentVolumeClaim for Postgres. Object storage is configured via env (S3_ENDPOINT, S3_BUCKET); the reference deployment uses a self-hosted MinIO under the same namespace.
Updating
Roll updates by changing the image tag and reapplying the kustomization. Database migrations are applied on agentflow-api startup behind a leader-election lock.
kubectl -n agentflow set image deploy/agentflow-api api=registry.example.com/agentflow-api:<sha>
kubectl -n agentflow rollout status deploy/agentflow-api
Pin image tags to commit SHAs in production. Avoid :latest. The reference CI/CD pipeline builds with the SHA and runs a kubectl set image.
Single-node Docker Compose
For a single-node dev environment, each repo ships docker-compose.yml:
cd agentflow-api
docker compose up -d
This is appropriate for personal dev only. Production deployments should use Kubernetes.