Self-hosting
Reference

Configure a production deployment

Harden an Agent Barn Kubernetes deployment for production with isolated environments, stable-secret custody, least-privilege access, durable storage, backups, monitoring, staged releases, and recovery preparation.

For
Platform Administrators, DevOps engineers, security engineers, and Kubernetes operators
On this page
  1. Overview
  2. Production baseline
  3. Before you begin
  4. 1. Isolate production and staging
  5. 2. Protect the deployment path
  6. 3. Protect stable keys and credentials
  7. 4. Restrict Kubernetes access
  8. 5. Plan storage and backups
  9. 6. Secure networking and TLS
  10. 7. Configure production providers
  11. 8. Plan capacity and availability
  12. 9. Configure monitoring and alerts
  13. 10. Prepare disaster recovery
  14. 11. Stage and verify releases
  15. 12. Complete production go-live
  16. Current availability constraints
  17. Production checklist
  18. Security considerations
  19. Troubleshooting
  20. Next steps

Production readiness outcome

A protected, recoverable deployment with known limits

Complete this guide before admitting production users or running business-critical Agents.

  • Production and staging state are isolated.
  • Deployment, runtime access, and stable keys have explicit owners.
  • Data can be restored from an externally managed recovery set.
  • Releases pass through staging, backup, and post-deploy verification.
  • Operators understand the default single-replica availability boundary.

Overview

A running Kubernetes installation is the starting point. Production readiness adds controls that the default Helm charts do not create automatically.

This guide assumes you have completed the self-hosted configuration, deployed Agent Barn to Kubernetes, and verified the API, UI, databases, ingress, and Agent lifecycle.

ConfigurationStagingTested releaseVerified recoveryProtected productionOperator response

Production baseline

The repository supplies a functional single-cluster platform. The matrix makes the remaining operator responsibilities explicit.

RequirementDefault supportOperator action
Environment separationProduction and staging namespacesSupply distinct keys, databases, hosts, and kubeconfigs
TLS ingressTraefik and cert-manager integrationConfigure DNS, issuer, and certificate monitoring
Persistent databasesSingle-replica PostgreSQL StatefulSetsSelect durable storage and external backups
Agent workspacesOne PVC per AgentBack up PVCs when continuity is required
Background processingRedis, worker, and reconciliation CronJobMonitor worker, Redis, and Event Delivery health
MonitoringPrometheus, Grafana, and AlertmanagerRoute alerts and add cluster-capacity monitoring
Stable secretsKubernetes SecretsKeep authoritative copies in a protected secret manager
High availabilityNot providedDesign and validate a custom HA architecture if required
AutoscalingNot providedCapacity-plan and add tested controls if required
Network isolationInternal ClusterIP ServicesAdd cluster-compatible NetworkPolicies or equivalent controls
Database recoveryNot providedConfigure retention, encryption, backups, and restore tests
Deployment approvalBranch-triggered workflowProtect main and require review before merge

Before you begin

Assign a production owner, security contact, and on-call operator. Document availability, recovery point, recovery time, retention, maintenance-window, and provider-budget requirements.

Estimate concurrent Agents, message and Tool Call volume, storage growth, and provider rate limits. Prepare:

  • A staging namespace and environment-specific kubeconfigs
  • A protected secret manager
  • A backup system compatible with PostgreSQL and the selected StorageClass
  • Production DNS control and an operator-monitored alert destination
  • A tested release artifact or protected deployment workflow

Isolate production and staging

The standard layout deploys two namespace-isolated stacks into the same cluster.

Branch: mainProductionagent-farmProduction keys, data, DNS, kubeconfigs, and sender
Branch: stagingStagingagent-farm-stagingStaging-only keys, data, DNS, kubeconfigs, and sender
Production environment
NAMESPACE=agent-farm
ENVIRONMENT=production
Staging environment
NAMESPACE=agent-farm-staging
ENVIRONMENT=staging

Only the Kubernetes namespaces retain the agent-farm name after the Agent Barn rebrand, preserving existing workloads and PVC continuity.

Namespace isolation is not a separate cluster or provider security boundary. Use distinct application and LiteLLM database passwords, signing and encryption keys, bootstrap administrators, kubeconfigs, hosts, and sender subdomains.

The current workflow shares the registry, OpenRouter, Google OAuth, Cloudflare account and token, Slack alert webhook, Firecrawl password, and Firecrawl key unless operators change it. Shared inputs also share quota, revocation, and failure impact.

Verify that the staging API receives its release namespace as K8S_NAMESPACE; otherwise it can fall back to production when creating Agent workloads.

Shell
kubectl get deployment agentbarn-api \
  --namespace agent-farm-staging \
  -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="K8S_NAMESPACE")].value}{"\n"}'

Expected: agent-farm-staging.

Protect the deployment path

The GitHub workflow runs on pushes to main and staging, and on manual dispatch. Manual dispatch is accepted only from those branches. Production deploys from main into agent-farm; staging deploys from staging into agent-farm-staging.

Understand change detection and concurrency

  • Change detection compares with the latest successful deployment on the same branch.
  • A failed deployment does not advance that baseline.
  • Manual dispatch or an unavailable baseline builds all four Agent Barn images.
  • Branch-group concurrency does not cancel an in-progress deployment when a newer run starts.

Understand image behavior

ImageProductionStaging
APIlatestlatest-staging
UIlatestlatest-staging
HermesVersion-file tagVersion-file tag with -staging
OpenClawVersion-file tagVersion-file tag with -staging

The workflow stamps the git SHA into pod templates, forcing API and UI rollouts even though their branch tag moves. Use explicit, mutually compatible tags for a manual release bundle.

Protect stable keys and credentials

Keep authoritative production values in a protected secret manager. Store signing and encryption keys, database passwords, provider tokens, registry credentials, API-facing Kubernetes access, Grafana credentials, and alert webhooks outside populated repository files.

Stable secretRestore with
SECRET_SIGNING_KEYActive Agent Barn authentication sessions
AGENT_TOKEN_ENCRYPTION_KEYThe application database containing encrypted credentials and Agent keys
LITELLM_MASTER_KEYThe LiteLLM database and virtual-key state
PostgreSQL credentialsExisting initialized PostgreSQL volumes

Registry, OpenRouter, Cloudflare, Google OAuth, Slack webhook, and Grafana credentials are usually independently rotatable. Test emergency rotation without changing the stable recovery set.

Bootstrap administrator

PLATFORM_ADMIN_CREDENTIALS creates an administrator only when none exists. Updating the Secret later does not reset an existing account password. Create at least two independently controlled, named Platform Administrators and avoid routine use of the bootstrap account.

Restrict Kubernetes access

Use different identities for deployment and API runtime orchestration.

Deployment identity
  • Installs and upgrades releases
  • Manages chart-owned resources
  • Runs migrations and hooks
API pod identity
  • Manages namespaced Agent workloads
  • Reads Pods, health, and logs
  • Supports approved exec and port-forward operations

The API identity needs namespaced access to create Agent Deployments, Services, Secrets, ConfigMaps, and PVCs, and to inspect Pods, health, logs, exec, and port-forward operations. It should not access staging, unrelated namespaces, cluster Secrets, or nodes.

Verify the LiteLLM bootstrap identity

The LiteLLM key bootstrap Job runs as LITELLM_KEY_SERVICE_ACCOUNT. Verify that the configured account exists.

Shell
kubectl get serviceaccount \
  --namespace agent-farm \
  agent-farm-user

Audit effective permissions

Shell
kubectl auth can-i create deployments --namespace agent-farm
kubectl auth can-i create services --namespace agent-farm
kubectl auth can-i create secrets --namespace agent-farm
kubectl auth can-i create persistentvolumeclaims --namespace agent-farm
kubectl auth can-i get pods --namespace agent-farm
kubectl auth can-i get pods/log --namespace agent-farm

Repeat the checks with impersonation or the intended kubeconfig, then confirm that the same identity cannot read another namespace.

Plan storage and backups

The default deployment requests at least 19 GiB before any Agents: 5 GiB for application PostgreSQL, 2 GiB each for LiteLLM and Firecrawl PostgreSQL, and 10 GiB for Prometheus. Every Agent PVC requests another 1 GiB.

The default k3s local-path StorageClass is node-local. Choose storage that meets the production durability target. Changing STORAGE_CLASS on an existing PostgreSQL StatefulSet is not an in-place migration because its volume claim template is immutable.

Back up the complete recovery set

Recoverable Agent Barn deploymentRestore these branches together
DatabasesApplication PostgreSQLLiteLLM PostgreSQLFirecrawl PostgreSQL
Agent dataRequired Agent PVCsCompatible images and chartsDeployment configuration
Stable keysSigning keyAgent encryption keyLiteLLM master key

Agent Barn does not install a database or Agent PVC backup controller. Integrate an external backup system, define frequency, retention, off-cluster storage, encryption, access, RPO/RTO, restore order, verification, and failure ownership.

Redis has no persistent volume in the current chart. Durable Domain Event intent remains in PostgreSQL, and reconciliation can republish eligible Event Deliveries when Redis returns.

Secure networking and TLS

SurfaceExposureRoute
Web applicationPublic/
Product APIPublic/api
GrafanaOperator-only when neededDedicated host
Metrics and IngestInternalNo public ingress
PostgreSQL, Redis, LiteLLM, FirecrawlInternalClusterIP Services
Production hostnames
UI_HOST=agentbarn.example.com
API_HOST=api.agentbarn.example.com
GRAFANA_HOST=grafana.agentbarn.example.com
WEB_APP_URL=https://agentbarn.example.com

Confirm DNS resolution, ports 80 and 443, certificate issuance and renewal monitoring, API-to-Service routing, and restricted Grafana authentication.

Introduce network isolation in staging

The charts do not create NetworkPolicies. If the cluster enforces them, allow only required UI-to-API, service-to-database, worker-to-Redis, LiteLLM-to-provider, Firecrawl, Agent, and Prometheus flows. Test egress carefully: a bad policy can leave Agents running but unable to reach model or messaging providers.

Configure production providers

OpenRouter and LiteLLM

Use a production-dedicated OpenRouter key when isolation is required. Assign its budget, credit limit, rate limits, billing alerts, owner, rotation path, and emergency replacement procedure. The OpenRouterCreditsLow alert is useful only when the provider key has a credit limit; an unlimited key reports infinite remaining credit.

Keep LITELLM_MASTER_KEY stable and separate from the OpenRouter provider key.

Transactional email

Environment
SENDER_EMAIL=[email protected]

Transactional email requires the Cloudflare account ID, API token, and sender address, plus a verified sending domain. Verify invitations, password recovery, lifecycle notifications, reputation, and quota. Use a different sender subdomain for staging.

Production and staging share the Cloudflare account, token, and account quota in the current workflow, so rotation and quota exhaustion can affect both.

Google Workspace

OAuth callback
https://agentbarn.example.com/api/v1/integrations/google/callback

Register the exact production callback. If an OAuth client is shared with staging, register that callback too; separate clients provide stronger failure and consent-screen isolation.

Firecrawl

Treat the platform Firecrawl key as a production credential. Its Services remain internal, but Firecrawl makes outbound requests, so enforce appropriate egress, destination, abuse-prevention, and capacity policies.

Plan capacity and availability

API, UI, worker, LiteLLM, Redis, all PostgreSQL databases, each Firecrawl component, Prometheus, Grafana, and Alertmanager run as single replicas by default.

Each Agent adds a Deployment, pod, Service, 1 GiB PVC, CPU and memory demand, model usage, platform API traffic, and monitoring traffic. Agent resource profiles are not configurable through .env.deploy.

Load-test representative Hermes and OpenClaw workloads in staging, including concurrent Agents, peak tools, large model responses, browser or Firecrawl work, Template and Skill loading, and restart behavior.

If the availability target requires multiple replicas, replication, or failover, treat that as custom architecture and validation work—not an environment-variable toggle.

Configure monitoring and alerts

Alerting and Grafana
SLACK_ALERTS_WEBHOOK_URL=REPLACE_WITH_PRODUCTION_WEBHOOK
GRAFANA_ADMIN_PASSWORD=REPLACE_WITH_STRONG_PASSWORD
GRAFANA_HOST=grafana.agentbarn.example.com
API and IngestUnavailable services, absent API targets, and elevated API 5xx responses
Data servicesApplication PostgreSQL and LiteLLM availability
AgentsUnavailable scrape targets, unhealthy Agents, and Agents in ERROR
ActivityElevated Tool Call errors and invalid Slack credentials
ProvidersLow or unavailable OpenRouter credits

For every alert, document severity, on-call owner, response target, diagnostic link, escalation, recovery action, and user-notification threshold. Trigger a controlled staging alert before go-live.

Understand monitoring scope

Prometheus requests a 10 GiB PVC and retains 15 days by default. The namespace-scoped configuration does not collect cluster-wide node, kubelet, or cAdvisor metrics.

Add cluster monitoring for nodes, filesystems, volumes, container CPU and memory, the control plane, ingress, and cert-manager. Grafana dashboards are operational views, not audit logs or business records.

Prepare disaster recovery

Write and schedule a recovery exercise using this minimum sequence:

  1. Provision an isolated recovery namespace or cluster.
  2. Restore stable keys and the three PostgreSQL databases.
  3. Restore required Agent PVCs and compatible deployment artifacts.
  4. Deploy without changing the restored keys and verify the expected schema.
  5. Verify authentication, LiteLLM virtual keys, and a model request.
  6. Verify Shared Credentials and Agent credentials can decrypt.
  7. Start a test Agent and verify messages, Tool Calls, and costs.
  8. Verify Event Delivery reconciliation, monitoring, and alerts.

Preserve version compatibility

Record the git commit, API/UI and runtime image tags, chart versions, Alembic revision, PostgreSQL and LiteLLM versions, backup time, and secret-manager references with every recovery set. Do not restore into an arbitrary application version.

Plan migration rollback

Database migrations run as a Helm pre-install/pre-upgrade hook. Helm rollback changes manifests and images; it does not reverse Alembic migrations. Before schema changes, review compatibility, back up the application database, test upgrade and recovery in staging, and decide whether rollback uses an older compatible image or a database restore.

Stage and verify releases

ChangeStagingVerificationBackupProductionPost-deploy verification

In staging, verify API and UI health, administrator login, Organization isolation, invitations and email, OAuth, Agent creation, Hermes and OpenClaw startup, messaging platforms, LiteLLM requests, Activity, Tool Calls, logs, costs, Shared Credentials, Event Delivery processing, dashboards, alerts, migrations, and restart recovery.

Use dedicated staging chat applications, credentials, and data. Do not test with production workspaces or customer conversations.

Immediately before production

Shell
kubectl config current-context
kubectl get pods --namespace agent-farm
kubectl get pvc --namespace agent-farm
kubectl get certificate --namespace agent-farm

Confirm the production backup completed, is readable, and is associated with the matching stable-key set.

Complete production go-live

Verify releases, workloads, storage, ingress, certificates, and the public API.

Helm releases
helm list --namespace agent-farm
Workloads
kubectl get deployments,statefulsets,pods,jobs,cronjobs \
  --namespace agent-farm
Storage and ingress
kubectl get pvc,ingress,certificate \
  --namespace agent-farm
API health
curl --fail https://api.agentbarn.example.com/api/v1/health

Then sign in with a named Platform Administrator, select the production Organization, invite a controlled test user, verify email enrollment, and start a non-sensitive test Agent. Send a message and verify the response, Activity, Tool Calls, cost attribution, Agent metrics, and alert state. Retire the test Agent according to policy and record the deployed commit and verification result.

Current availability constraints

AreaCurrent default
API, UI, worker, LiteLLMOne replica each; replacements are non-overlapping
PostgreSQLThree independent, single-replica StatefulSets
RedisOne replica without persistent Kubernetes storage
FirecrawlOne replica per component
PrometheusOne replica with 15-day retention
Grafana and AlertmanagerOne replica each
Agent storageOne ReadWriteOnce PVC per Agent
Autoscaling and disruption budgetsNot configured
NetworkPoliciesNot configured
Backups and database replicationNot configured
Cross-cluster failoverNot configured

These defaults fit a lean self-hosted platform whose operators accept single-node and maintenance risk. Stricter availability objectives require explicit architecture work.

Production checklist

Use these cards during the change review and final go-live call.

  • Identity and access

  • Secrets

  • Data and recovery

  • Networking

  • Providers

  • Operations

Security considerations

  • Treat deployment credentials, workflow changes, stable keys, and backups as production security surfaces.
  • Never mount cluster-admin access into the API or expose metrics, Ingest, databases, Redis, LiteLLM, or Firecrawl publicly.
  • Use separate environment credentials when shared provider quota, revocation, or access is unacceptable.
  • Restrict Grafana, encrypt backups, and test recovery access.
  • Do not place credentials in Templates, Skill files, logs, alert annotations, or privilege reasons.
  • Review chat-platform access, model allowlists, and provider budgets before connecting production channels.
  • Restart Agents deliberately when generated runtime configuration changes; platform deploys do not rebuild every running Agent.
  • Treat stable-key rotation and StorageClass changes as migrations.

Planned Organization suspension and platform-audit capabilities are not substitutes for these production controls.

Troubleshooting

SymptomLikely causeResolution
A merge to main deployed unexpectedlyProduction deploys on pushes to mainAdd or correct branch protection and required review.
Two production deployments overlapA deployment path bypassed branch-group concurrencyInspect active runs and standardize on the supported workflow.
Staging cannot create litellm-api-keyThe configured ServiceAccount does not match the provisioned identityReconcile the workflow value and staging bootstrap manifest.
Staging creates Agent resources in productionK8S_NAMESPACE or the API kubeconfig points to productionStop staging Agents and correct namespace and kubeconfig wiring.
The production API can access unrelated namespacesThe mounted kubeconfig is too privilegedReplace it with a dedicated namespace-scoped API identity.
Database authentication fails after deploymentThe configured password differs from the initialized volume passwordRestore the prior value or perform a coordinated database rotation.
Restored credentials cannot decryptThe wrong Agent encryption key was restoredRestore the key belonging to that application database backup.
Restored LiteLLM Agent keys failThe wrong master key or LiteLLM database was restoredRestore the matching LiteLLM master key and database.
PVCs remain PendingThe StorageClass is unavailable or incompatibleSelect a supported ReadWriteOnce StorageClass.
Data is lost after node failureNode-local storage was used without backup or replicationRestore from backup and adopt an appropriate durable storage design.
Model requests fail during deploymentLiteLLM is being replaced without an overlapping replicaWait for readiness and schedule future changes in a maintenance window.
An Agent still uses old runtime configurationExisting Agent workloads were not rebuiltStop and start the affected Agent deliberately.
Event Deliveries remain PendingRedis, the worker, or reconciliation is unavailableInspect Redis, worker readiness, and the reconciliation CronJob.
Prometheus lacks CPU or memory metricsNamespace monitoring does not discover node or cAdvisor metricsAdd cluster-level infrastructure monitoring.
OpenRouter credit alerts are not usefulThe provider key has no credit limitConfigure a provider limit and validate the metric.
Staging exhausts the email quotaBoth environments share the Cloudflare account quotaLimit staging sends or separate provider accounts.
Helm rollback does not restore old behaviorThe database schema remained migratedUse the documented compatibility or database-restore procedure.
TLS remains unreadyDNS, ingress, or the fixed ClusterIssuer is incorrectInspect Certificate, Challenge, Ingress, and ClusterIssuer resources.

Next steps

Documentation