Skip to content

Kubernetes Deployment

Agentcy ships a Helm chart and reference manifests that work on any standards-compliant Kubernetes cluster (1.27+). For provider-specific guides, see AWS EKS or the GKE section in GCP.

Architecture

Stateless tier (frontend + API) scales horizontally via HPA. The data tier is either bundled (StatefulSets with PVCs) or external (managed services) — set per-component in values.yaml.

What You Get

A namespace with:

  • agentcy-api Deployment (2+ replicas) + Service + HPA
  • agentcy-frontend Deployment (2+ replicas) + Service
  • Ingress (NGINX or any IngressClass) with TLS via cert-manager
  • StatefulSets for PostgreSQL, Neo4j, Redis (optional — disable to use managed databases)
  • Secrets for credentials, ConfigMap for non-sensitive config
  • ServiceMonitor for Prometheus (optional)

Prerequisites

  • Kubernetes 1.27+
  • kubectl and helm 3.12+
  • An ingress controller (NGINX, Traefik, etc.) and cert-manager if you want TLS automation
  • A storage class that supports ReadWriteOnce PVCs (any cloud default works)

Quick Install via Helm

Add the chart repo:

bash
helm repo add agentcy https://charts.agentcylabs.com
helm repo update

Create a values.yaml:

yaml
image:
  registry: ghcr.io/agentcy
  tag: latest
  pullPolicy: IfNotPresent

api:
  replicaCount: 2
  resources:
    requests:
      cpu: 250m
      memory: 512Mi
    limits:
      cpu: 1000m
      memory: 1Gi
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 8
    targetCPUUtilizationPercentage: 70

frontend:
  replicaCount: 2
  resources:
    requests:
      cpu: 100m
      memory: 256Mi

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: agentcy.example.com
      paths:
        - path: /api
          backend: api
        - path: /
          backend: frontend
  tls:
    - hosts: [agentcy.example.com]
      secretName: agentcy-tls
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod

# Bundled databases — disable any of these to use managed services
postgresql:
  enabled: true
  auth:
    username: agentcy
    database: agentcy
    existingSecret: agentcy-postgres
  primary:
    persistence:
      size: 50Gi

# Context Engine — pick ONE provider. Default is Basic (Neo4j-compatible).
contextEngine: basic   # or "advanced"

# Basic provider: Neo4j-compatible graph store
neo4j:
  enabled: true        # auto-disabled when contextEngine=advanced
  auth:
    existingSecret: agentcy-neo4j
  resources:
    requests:
      cpu: 500m
      memory: 2Gi
    limits:
      cpu: 2000m
      memory: 4Gi
  persistence:
    size: 100Gi

# Advanced provider: kyma columnar engine on object storage.
# See https://getkyma.dev for the engine details.
kyma:
  enabled: false       # set to true when contextEngine=advanced
  image:
    repository: ghcr.io/agentcylabs/kyma
    tag: latest
  replicaCount: 2
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2000m
      memory: 4Gi
  objectStore:
    # Any S3-compatible bucket: AWS S3, GCS (interop), Cloudflare R2, MinIO.
    type: s3
    endpoint: ""        # leave empty for AWS S3, set for R2/MinIO
    bucket: agentcy-kyma
    region: us-east-1
    existingSecret: agentcy-kyma-s3   # AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
  catalog:
    # kyma's catalog can live in the same Postgres or a separate database
    existingSecret: agentcy-kyma-catalog
    secretKey: url
  otlp:
    enabled: false      # exposes :4317 for direct OTLP ingest

redis:
  enabled: true
  auth:
    enabled: false  # internal only
  master:
    persistence:
      size: 10Gi

llm:
  provider: anthropic
  apiKeySecret:
    name: agentcy-llm
    key: api-key

auth:
  provider: local         # or "oidc"
  jwtSecretName: agentcy-jwt

Create the secrets:

bash
kubectl create namespace agentcy

kubectl -n agentcy create secret generic agentcy-llm \
    --from-literal=api-key=sk-ant-...

kubectl -n agentcy create secret generic agentcy-jwt \
    --from-literal=secret=$(openssl rand -hex 32)

kubectl -n agentcy create secret generic agentcy-postgres \
    --from-literal=password=$(openssl rand -hex 16)

kubectl -n agentcy create secret generic agentcy-neo4j \
    --from-literal=password=$(openssl rand -hex 16)

Install:

bash
helm install agentcy agentcy/agentcy \
    --namespace agentcy \
    --values values.yaml

Check rollout:

bash
kubectl -n agentcy get pods
kubectl -n agentcy get ingress

Using Managed Databases

For production, prefer managed Postgres (RDS, Cloud SQL, AlloyDB, Supabase), managed Redis (ElastiCache, Memorystore, Upstash), and either AuraDB (Basic) or a managed kyma deployment (Advanced — Agentcy Cloud, or your own kyma cluster). Set the bundled charts to enabled: false and supply external connection strings:

yaml
postgresql: { enabled: false }
neo4j:      { enabled: false }
kyma:       { enabled: false }
redis:      { enabled: false }

externalDatabases:
  postgres:
    url: postgres://agentcy:***@postgres.internal:5432/agentcy
  redis:
    url: redis://redis.internal:6379

  # Basic provider — Neo4j-compatible (AuraDB or self-managed)
  neo4j:
    uri: neo4j+s://xxxxx.databases.neo4j.io
    user: neo4j
    passwordSecret:
      name: agentcy-neo4j
      key: password

  # OR Advanced provider — external kyma cluster
  kyma:
    baseUrl: https://kyma.internal:8080
    database: kyma
    tokenSecret:
      name: agentcy-kyma
      key: token

Raw Manifests (no Helm)

If you can't use Helm, render the chart and check the manifests in:

bash
helm template agentcy agentcy/agentcy --values values.yaml > agentcy.yaml
kubectl apply -f agentcy.yaml

This is also the recommended path for GitOps tools (Argo CD, Flux) — commit agentcy.yaml (or the chart + values) to your manifests repo.

Probes

The API exposes:

PathPurpose
/healthLiveness — 200 OK if the process is up
/readyReadiness — checks Postgres, Neo4j, Redis
/metricsPrometheus exposition

The chart wires liveness and readiness probes by default. Don't disable them — they prevent traffic from hitting a pod whose database connection has dropped.

Horizontal Scaling

The API and frontend are stateless. Scale via HPA on CPU or by setting replicaCount directly. Sticky sessions are not required — JWTs travel with each request.

Stateful tier scaling depends on your databases:

  • Postgres: scale vertically; add read replicas if your workload demands it.
  • Context Engine — Basic: Neo4j Community edition is single-node. For HA, switch to Neo4j Enterprise with causal cluster, or AuraDB.
  • Context Engine — Advanced (kyma): compute is stateless and scales horizontally — bump kyma.replicaCount. Storage is your S3-compatible bucket; the catalog is shared via Postgres CAS commits. See getkyma.dev for multi-node details.
  • Redis: switch the chart to architecture: replication for replicas.

Pod Security

The chart sets runAsNonRoot: true, drops all capabilities, and uses a read-only root filesystem. If your cluster enforces Pod Security Admission restricted, no overrides are needed.

Network Policies

A starter NetworkPolicy that locks the API to ingress from the frontend and the ingress controller is included — enable with:

yaml
networkPolicy:
  enabled: true
  ingressNamespaceSelector:
    kubernetes.io/metadata.name: ingress-nginx

Observability

If you run kube-prometheus-stack, enable the ServiceMonitor:

yaml
serviceMonitor:
  enabled: true
  interval: 30s

Logs go to stdout — pick them up with the agent of your choice (Fluent Bit, Vector, OTel Collector).

Backups

For self-managed databases use the Velero chart with PVC snapshots, or run a CronJob with pg_dump and neo4j-admin database dump. Managed databases handle this for you.

Upgrading

bash
helm repo update
helm upgrade agentcy agentcy/agentcy --namespace agentcy --values values.yaml

The API runs migrations on boot. Helm's rolling update keeps the old replicas serving traffic until the new ones are ready.

Troubleshooting

agentcy-api pods stuck in CrashLoopBackOff

bash
kubectl -n agentcy logs deployment/agentcy-api --previous

Most failures are credential-related. Verify the secrets exist and the connection strings resolve from inside the cluster (kubectl run -it --rm debug --image=postgres:16 -- psql ...).

Ingress returns 502

bash
kubectl -n agentcy get endpoints

Empty endpoints means no pod is Ready. Check the readiness probe — it fails until all three databases respond.

Neo4j PVC won't bind

The default chart asks for a ReadWriteOnce 100Gi volume. If your storage class can't provision this, set neo4j.persistence.size smaller or disable the bundled chart and use AuraDB.

Next Steps

  • AWS EKS — EKS-specific extras (IRSA, ALB ingress, EBS CSI tuning)
  • GCP — GKE + Cloud SQL pattern
  • Writing Rego Policies — enforce zero-trust at the agent layer

Built by AgentcyLabs. For in-house deployment or Agentcy Cloud (PaaS) access, visit agentcylabs.com.