Skip to content

Resources & implementation

Everything needed to run Agentfy.ai 2.0. Hetzner-centric (cheap compute, co-located, EU/GDPR); AWS shrinks to optional S3 / KMS / SES — or zero. Cognito and Secrets Manager are not used. For when (if ever) any of this moves to AWS, see the Cloud strategy.

Which of this inventory is actually deployed

The list below is the plan. What runs today is declared in a second repository, Agentfy/gitopsTwo repositories lists it file by file. The short version, and it changes four rows here:

  • api, app, admin and Redis run in the dev contour only. There is no prod equivalent of agentfy-apps/dev/.
  • Postgres is not in the cluster. It runs on two dedicated Hetzner VMs configured by ansible/roles/postgres; the api's DATABASE_URL points at 10.0.1.1:5432. No CloudNativePG anywhere.
  • LightRAG does not exist — no service, no chart, no Application.
  • Object storage is settled in infrastructure and unused in code.terraform/storage.tf creates one private, versioned Hetzner Object Storage bucket per contour, and puts AWS S3 to work for Terraform state and backups only. This repository's only storage driver still writes to a local filesystem path, so nothing reads or writes those buckets yet.

One more correction, to Secrets & keys below: infra credentials — the KEK included — reach the cluster from HashiCorp Vault through the External Secrets Operator, not from a hand-written Kubernetes Secret. A Kubernetes Secret is still what the pod sees; it is produced, not authored.

Kubernetes (Hetzner)

A single k3s cluster (like Ranch) with three node pools — the control plane runs on its own node(s), separate from workloads. Full topology + autoscaling: Cluster & nodes.

poolrunsscaling
control-plane (tainted, isolated)k3s server: API server · etcd · scheduler · controller-managerfixed: 1 (dev) / 3 (prod HA)
core (always-on)api, app, admin, LightRAG service, Postgres/RedisHPA per app + cluster-autoscaler on the pool
workers (tainted, node-role: workers)ephemeral worker Jobs (+ heavy tasks)scale-to-zero per task; cluster-autoscaler 0 → N under load

Plus: Ingress (Traefik/nginx) + cert-manager (TLS), a container registry, GitOps CD (ArgoCD), cluster-autoscaler + HPA/VPA, per-tenant ResourceQuota/LimitRange, and NetworkPolicy (default deny-all egress; allowlist Core WS + required domains).

Deployables

deployablepoollifecycle
apicorepersistent (Core) and ephemeral brain (same image, run per-turn)
app / admincorepersistent (Nuxt)
LightRAG service (Python)corepersistent; agent/knowledge is a thin gateway to it
workerworkerson-demand k8s Job per task; bundles Playwright + Chromium (launches a browser in-pod for browser tasks — no separate pool); ttlSecondsAfterFinished + idle reaper

See Worker on Kubernetes for the Job lifecycle.

Datastores

storewhat it holdshost
Postgres (self-host)app data · chat · usage/billing · encrypted secrets · vector (pgvector) · graph (AGE) for LightRAGHetzner
RedisBullMQ queue · pub/sub (events) · locks · idle timersHetzner
Object storagesystem/file (artifacts, avatars, docs, invoice PDFs, browser/workspace snapshots)S3 / R2 / Hetzner OS (open)
(Neo4j + Qdrant/Milvus)only if the large-scale LightRAG path is chosen instead of pgvector+AGEHetzner

Postgres must be self-hosted because the unified LightRAG backend needs the pgvector + Apache AGE extensions (managed Neon blocks AGE). Postgres therefore carries app data and the agent's vector + graph — one store for small/medium scale.

Knowledge / LightRAG infra

  • A separate Python service on the core pool; agent/knowledge proxies to it over MCP.
  • Storage backend by scale: many small basesPostgres (pgvector + AGE); millions in one baseNeo4j + Qdrant/Milvus. Benchmark before committing.
  • Ingestion is async/queued (BullMQ), incremental, token-budgeted — the LLM extraction is the cost wall, not storage. Per-knowledge-base workspaces isolate tenants.

See Knowledge — LightRAG.

Secrets & keys

  • Agent secrets: encrypted in Postgres (app-layer envelope, AES-256-GCM, DEK wrapped by a KEK) — no Secrets Manager. See Agent secrets.
  • KEK: a k8s Secret injected only into api (MVP) → optional AWS KMS (wrap DEKs only) later.
  • Auth: own JWT (issuer = Core) — no Cognito. The same scheme mints short-lived runtime session tokens injected into the worker Job (no long-lived creds in the pod).

Observability & ops

  • Sentry (errors), Loki/Grafana (logs/metrics) self-hosted.
  • Backups: Postgres (PITR) + object storage; audit log (admin/audit) of runtime sessions.
  • HA: replicated core deployments; Postgres/Redis with replicas as the product grows.

External SaaS (neither Hetzner nor AWS)

  • Claude API (Anthropic) — LLM (system/llm).
  • Payment — PayPal (+ Stripe?).
  • Email/SMTPResend (MVP) → AWS SES at scale; swappable behind notification/email.

AWS footprint — what (if anything) stays

AWS serviceuseneeded?
S3object storage for system/fileoptional — vs Hetzner OS / R2
KMSwrap the secrets KEKoptional — vs KEK in a k8s Secret
SEStransactional email at scalelater — MVP starts on Resend (non-AWS)
Cognitodropped (own JWT)
Secrets Managerdropped (encrypted in Postgres)
Bedrock / Lambda / DynamoDB / Step Functionsdropped (Claude API / BullMQ / Postgres)

Net: Agentfy.ai 2.0 can run fully on Hetzner (+ Claude/payment/email as external SaaS); AWS is reduced to at most a few managed conveniences (S3/KMS/SES), each individually optional.

ConcernWhere
k8s (api/app/admin/worker/LightRAG)Hetzner
Postgres (+ pgvector + AGE + encrypted secrets), RedisHetzner (self-host)
Object storageHetzner OS or AWS S3 / R2 (open)
Secrets KEKk8s Secret (MVP) → KMS (open)
EmailResend (MVP) → AWS SES at scale
LLM, paymentexternal

See Open questions for what's still undecided (storage provider, vector/graph backend by scale, billing provider).