---
title: "Kubernetes Deployment"
version: "v0.24.0"
canonical: "https://docs.obot.ai/v0.24.0/installation/kubernetes-deployment"
unreleased: false
---

<a id="obot-doc-kubernetes-deployment"></a>

# Kubernetes Deployment

Deploy Obot on Kubernetes for production-grade reliability, scalability, and high availability.

> **INFO**
>
> Helm Chart Reference
>
> For a complete list of all available Helm chart configuration values, see [charts.obot.ai](https://charts.obot.ai/).

<a id="obot-doc-prerequisites"></a>

## Prerequisites

- **Helm**
- **PostgreSQL 17+**
- **Object storage or a persistent volume for published workflows** (for production)
- **StorageClass** (for production)
- **Encryption provider** (AWS KMS, GCP KMS, or Azure Key Vault recommended)

<a id="obot-doc-minimum-cluster-requirements"></a>

### Minimum Cluster Requirements

- **Nodes**: 1+ nodes
- **CPU**: 2 cores
- **Memory**: 4GB

<a id="obot-doc-recommended-cluster-requirements"></a>

### Recommended Cluster Requirements

- **HA Cluster**
- **CPU**: 4 cores for Obot
- **Memory**: 8GB for Obot

<a id="obot-doc-helm-installation"></a>

## Helm Installation

Obot provides a Helm chart for easy deployment [here](https://charts.obot.ai).

The chart has sane defaults for a test cluster.

<a id="obot-doc-production-installation"></a>

### Production Installation

Create a `values.yaml` file with your production configuration:

```yaml
# Optionally customize replica count for high availability
# replicaCount: 2

# Enable ingress or use a service of type loadbalancer to expose Obot
ingress:
  enabled: true
  hosts:
    - <your obot hostname>

# This can be turned off because we are persisting data externally in PostgreSQL and S3
persistence:
  enabled: false

# In this example, we will be using S3 and AWS KMS for encryption.
# Sensitive values must be configured under secret.
secret:
  # this should have IAM permissions for S3 and KMS
  AWS_ACCESS_KEY_ID: <access key>
  AWS_SECRET_ACCESS_KEY: <secret key>

  # This should be set to avoid ratelimiting certain actions that interact with github, such as server sources
  GITHUB_AUTH_TOKEN: <PAT from github>

  # optional - this will be generated automatically if you do not set it
  OBOT_BOOTSTRAP_TOKEN: <some random value>

  # Point this to your postgres database
  OBOT_SERVER_DSN: postgres://<user>:<pass>@<host>/<db>

  # Setting these is optional, but you'll need to setup a model provider from the Admin UI before using chat.
  # You can set either, neither or both.
  OPENAI_API_KEY: <openai api key>
  ANTHROPIC_API_KEY: <anthropic api key>

# Non-sensitive values must be configured under config.
config:
  AWS_REGION: <aws region>

  # Enable encryption
  OBOT_SERVER_ENCRYPTION_PROVIDER: aws
  OBOT_AWS_KMS_KEY_ARN: <your kms arn>

  # Store published workflows in external object storage
  # Options are s3, azure, gcs, and custom
  OBOT_ARTIFACT_STORAGE_PROVIDER: s3
  OBOT_ARTIFACT_STORAGE_BUCKET: <artifact bucket name>
  OBOT_ARTIFACT_S3_REGION: <aws region>

  OBOT_SERVER_HOSTNAME: <your obot hostname>
```

<a id="obot-doc-high-availability"></a>

### High Availability

To enable a high availability setup, uncomment the `replicaCount` line and set it to `2` or higher. An external PostgreSQL database and published workflow storage are required for HA.

For published workflow storage in HA, use one of these:

- External object storage such as S3, GCS, Azure Blob Storage, or an S3-compatible service
- The `persistence` PVC with `ReadWriteMany` access so all replicas can share `/data`

For detailed configuration options, see:

- **[Server Configuration](https://docs.obot.ai/v0.24.0/configuration/server-configuration.md)** - All available environment variables, including published workflow storage configuration
- **[Workflow Sharing](https://docs.obot.ai/v0.24.0/functionality/workflow-sharing.md)** - How shared workflows work and how to configure their storage
- **[Encryption Providers](https://docs.obot.ai/v0.24.0/configuration/encryption-providers/aws-kms.md)** - KMS encryption setup

<a id="obot-doc-cloud-specific-guides"></a>

## Cloud-Specific Guides

For detailed cloud-specific deployment instructions:

- [Google Kubernetes Engine (GKE)](https://docs.obot.ai/v0.24.0/installation/reference-architectures/gcp-gke.md)
- [Amazon Elastic Kubernetes Service (EKS)](https://docs.obot.ai/v0.24.0/installation/reference-architectures/aws-eks.md)
- [Azure Kubernetes Service (AKS)](https://docs.obot.ai/v0.24.0/installation/reference-architectures/azure-aks.md)

<a id="obot-doc-security-configuration"></a>

## Security Configuration

<a id="obot-doc-network-policy-for-mcp-servers"></a>

### Network Policy for MCP Servers

For production deployments, ensure the NetworkPolicy is enabled to restrict network access from MCP server pods:

```yaml
mcpNamespace:
  networkPolicy:
    enabled: true # This is already enabled by default
    dnsNamespace: kube-system  # Adjust if your DNS is in a different namespace
```

When enabled, this policy:

- Restricts MCP servers to only communicate with Obot, DNS, and public internet
- Blocks access to private IP ranges and internal cluster resources
- Prevents potential lateral movement if an MCP server is compromised

For details, see [MCP Deployments in Kubernetes - Network Policy](https://docs.obot.ai/v0.24.0/configuration/mcp-deployments-in-kubernetes.md#obot-doc-network-policy).

<a id="obot-doc-pod-security-admission-for-mcp-servers"></a>

### Pod Security Admission for MCP Servers

Obot applies Pod Security Standards to the MCP namespace using Pod Security Admission (PSA). The default configuration uses the **restricted** policy level for maximum security:

```yaml
mcpNamespace:
  podSecurity:
    enforce: restricted  # Can be: privileged, baseline, or restricted
    enforceVersion: latest
    audit: restricted
    auditVersion: latest
    warn: restricted
    warnVersion: latest
```

The restricted policy follows current Pod hardening best practices and provides the highest level of security. If you need more permissive settings, you can change to **baseline** or **privileged** levels.

For details, see [MCP Deployments in Kubernetes - Pod Security Admission](https://docs.obot.ai/v0.24.0/configuration/mcp-deployments-in-kubernetes.md#obot-doc-pod-security-admission).

<a id="obot-doc-restricting-obot-server-egress"></a>

### Restricting Obot Server Egress

The [Network Policy for MCP Servers](https://docs.obot.ai/v0.24.0/installation/kubernetes-deployment.md#obot-doc-network-policy-for-mcp-servers) above restricts the **MCP server pods**. It does not restrict the **Obot server** itself, which makes its own outbound connections as part of normal operation. In multi-tenant deployments or deployments with untrusted users, you may want to constrain which destinations the Obot server can reach, as a defense-in-depth measure.

If you want to constrain the Obot server's egress as a defense-in-depth measure, scope it tightly to your specific deployment — there is no safe blanket blocklist. Depending on your setup, the Obot server legitimately needs to reach private ranges (its database and in-cluster services such as a self-hosted model provider or the MCP namespace) and, with some cloud authentication methods, the cloud instance metadata endpoint (`169.254.169.254`), where it obtains credentials for integrations such as KMS.

<a id="obot-doc-agent-persistence"></a>

## Agent Persistence

By default, Obot Agent uses storage inside its pod, which means all agent state is lost if the pod restarts. For production deployments, configure a persistent `StorageClass`.

For complete guidance and examples (including AWS EBS, GCP Hyperdisk, and `nfs-subdir-external-provisioner`), see [Persistent Storage in Kubernetes](https://docs.obot.ai/v0.24.0/installation/kubernetes-persistent-storage.md).

<a id="obot-doc-workflow-sharing-in-kubernetes"></a>

## Workflow Sharing in Kubernetes

If `OBOT_ARTIFACT_STORAGE_PROVIDER` is unset, Obot stores published workflows on local disk at `/data/.local/share/obot/published-artifacts`.

The Helm chart's `persistence` PVC mounts at `/data`, so it covers that path.

<a id="obot-doc-use-the-existing-persistence-claim"></a>

### Use the Existing Persistence Claim

Use this when you do not want S3, GCS, Azure Blob Storage, or another object store for published workflows.

If you disable `persistence`, published workflow artifacts remain on pod-local disk and will be lost when the pod is replaced.

For a single Obot replica:

- Enable `persistence`
- Use `ReadWriteOnce` as the access mode
- This is appropriate for `replicaCount: 1`
- A block-storage-backed `StorageClass` such as EBS, PD, or Azure Disk is typically fine

For multiple Obot replicas:

- Enable `persistence`
- Use `ReadWriteMany` as the access mode
- All replicas must mount the same `/data` volume concurrently
- This requires a shared filesystem-backed `StorageClass`, such as NFS
- A single shared `ReadWriteOnce` claim is not a valid multi-replica setup

Example using dynamic provisioning for a single replica:

```yaml
replicaCount: 1

config:
  OBOT_ARTIFACT_STORAGE_PROVIDER: ""
  OBOT_ARTIFACT_STORAGE_BUCKET: ""

persistence:
  enabled: true
  storageClass: gp3
  accessModes:
    - ReadWriteOnce
  size: 10Gi
```

Example using an existing RWX claim for multiple replicas:

```yaml
replicaCount: 2

config:
  OBOT_ARTIFACT_STORAGE_PROVIDER: ""
  OBOT_ARTIFACT_STORAGE_BUCKET: ""

persistence:
  enabled: true
  existingClaim: obot-data-rwx
```

The `obot-data-rwx` claim itself must be provisioned with `ReadWriteMany`.

For more examples and storage-class guidance, see [Persistent Storage in Kubernetes](https://docs.obot.ai/v0.24.0/installation/kubernetes-persistent-storage.md).

<a id="obot-doc-next-steps"></a>

## Next Steps

1. **Configure Authentication**: Set up [auth providers](https://docs.obot.ai/v0.24.0/configuration/auth-providers.md)
2. **Add Model Providers**: Configure [model providers](https://docs.obot.ai/v0.24.0/configuration/model-providers.md)
3. **Set Up MCP Servers**: Configure [MCP servers](https://docs.obot.ai/v0.24.0/functionality/mcp-servers.md)
4. **Configure Monitoring**: Set up logging and metrics
5. **Review Security**: Enable authentication and encryption

<a id="obot-doc-related-documentation"></a>

## Related Documentation

- [Installation Overview](https://docs.obot.ai/v0.24.0/installation/overview.md)
- [Server Configuration](https://docs.obot.ai/v0.24.0/configuration/server-configuration.md)
- [Settings for Hosted MCP Server Deployments](https://docs.obot.ai/v0.24.0/configuration/mcp-deployments-in-kubernetes.md)
