Skip to main content
This guide shows you how to deploy Sure on Kubernetes using the official Helm chart. The chart supports web (Rails) and worker (Sidekiq) workloads, optional in-cluster PostgreSQL and Redis, and production-grade features like pre-upgrade migrations, pod security contexts, and horizontal pod autoscaling.

Prerequisites

  • Kubernetes >= 1.25
  • Helm >= 3.10
  • Basic familiarity with Kubernetes and Helm

Features

  • Web (Rails) deployment with service and optional ingress
  • Worker (Sidekiq) deployment
  • Optional database migrations via Helm hook job or initContainer
  • Optional subcharts for PostgreSQL (CloudNativePG) and Redis (OT-CONTAINER-KIT redis-operator)
  • Security best practices: runAsNonRoot, readOnlyRootFilesystem, no hardcoded secrets
  • Scalability: replicas, resources, topology spread constraints, optional HPAs
  • Optional CronJobs for custom tasks

Installation

Add Helm repositories

Add the Sure Helm repository:
If you plan to use the bundled PostgreSQL or Redis subcharts, add their repositories as well:

Quickstart (turnkey self-hosting)

This installs CloudNativePG operator with a Postgres cluster and Redis managed by the OT redis-operator.
For production stability, use immutable image tags (for example, image.tag=v1.2.3) instead of latest.
Do not pass production secrets with --set on the command line. Use a values file with restricted permissions or a Kubernetes Secret as described in Secrets management.
Expose the app via an ingress (see configuration below) or port-forward:
Navigate to http://localhost:8080 to access Sure. After creating your initial admin account, you can control future signups from Settings > Self-Hosting > Onboarding:
  • Open: Anyone can create an account from the registration page.
  • Invite-only: Signups stay enabled, but a valid invite code is required unless a default family is configured for invite-only onboarding.
  • Closed: The registration page is disabled for new signups.
If you do not want additional self-service registrations, switch the instance to Closed after the initial setup.

Configuration

Using external Postgres and Redis

To use external managed databases instead of the bundled subcharts, store connection strings in a Kubernetes Secret and reference them from your values file. See Secrets management for the general pattern.

Redis Sentinel (high availability)

The OT-CONTAINER-KIT Redis Operator supports a Sentinel failover layer for production HA deployments. When you enable Sentinel mode, the chart automatically injects REDIS_SENTINEL_HOSTS and REDIS_SENTINEL_MASTER into the web and worker pods so Sidekiq can do automatic master discovery and failover.
  • The application receives REDIS_SENTINEL_HOSTS (comma-separated Sentinel endpoints) and REDIS_SENTINEL_MASTER instead of REDIS_URL.
  • Sentinel authentication uses username default by default. Override with REDIS_SENTINEL_USERNAME if needed.
  • Provider precedence: explicit rails.extraEnv.REDIS_URLredisOperator.managed (with Sentinel if configured) → redisSimple.
  • Only one in-cluster Redis provider should be enabled at a time.

Active Record encryption keys

In self-hosted mode, Sure can derive Active Record encryption keys from SECRET_KEY_BASE automatically. If you want dedicated keys instead, provide these values through your app secret:
  • ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY
  • ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY
  • ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT
If you add custom encryption keys after the instance already has data, the chart’s normal migration flow is not enough to rewrite older plaintext values. db:prepare still handles schema setup and migrations, but existing rows need a one-off backfill after the app is running with the new keys:
The task is idempotent, so it is safe to rerun if needed. Keep the same SECRET_KEY_BASE for an existing release unless you are restoring from a backup created with the new value. Sure derives encryption keys from SECRET_KEY_BASE when dedicated ACTIVE_RECORD_ENCRYPTION_* values are not set, so changing it can prevent lookup of encrypted fields such as user email addresses and make email/password login appear invalid. If that happens after an encryption change, restore the previous secret values first, then run the backfill task if you are intentionally moving to dedicated encryption keys.

Deployment profiles

Simple single-node

Minimal setup for development or small deployments:
  • encryptionEnv.enabled: true tells the chart to wire the Active Record encryption keys from your secret into the app container.
  • SELF_HOSTED: "true" enables self-hosted behavior inside Sure.
  • Replace longhorn with a storage class that exists in your cluster.

HA k3s profile

High availability setup with multiple replicas and synchronous replication:

Secrets management

Generate strong secrets before creating the Kubernetes Secret:
Create a Kubernetes secret with the required credentials:
Apply the secret:
Reference the secret in your values:

Ingress configuration

Enable ingress to expose Sure externally:

Horizontal pod autoscaling

Enable HPAs for automatic scaling based on CPU utilization:

Updating

To update to a new version of Sure:
The chart will automatically run database migrations before deploying the new version.

Backup and restore

These steps cover PostgreSQL backups and restore. They do not automatically back up or restore uploaded files if your deployment stores them outside PostgreSQL.

PostgreSQL backups with CloudNativePG

CloudNativePG supports volume snapshot backups:

Manual backup

Create a manual backup of your PostgreSQL database:
[!NOTE] If you customized the PostgreSQL username or database name in your chart values, replace sure and sure_production in the backup and restore commands below.

Restore from backup

  1. Make sure app traffic is stopped or the deployment is in maintenance mode.
  2. Copy the SQL backup to the primary PostgreSQL pod:
  1. Restore the database:
  1. If your deployment uses uploaded files stored outside PostgreSQL, restore those separately using the matching volume snapshot or object-storage recovery process.
  2. Verify that the app starts cleanly and your data appears as expected.

Troubleshooting

View logs

Check pod status

Verify database connectivity

Run Helm tests

After installation, verify the deployment:

Uninstall

To remove Sure from your cluster:
This will not delete PersistentVolumeClaims. Before deleting PVCs, make sure the namespace does not contain volumes for anything other than Sure.

Pipelock (AI agent security proxy)

Pipelock is an optional security proxy that scans AI agent traffic for secret exfiltration, prompt injection, tool poisoning, and SSRF. It runs as a separate Deployment with two listeners:
  • Forward proxy (port 8888): Applies destination, SSRF, rate, budget, CONNECT-header DLP, and receipt controls to HTTPS tunnels from clients that honor the proxy variables. The chart does not configure TLS interception, so encrypted bodies stay opaque.
  • MCP reverse proxy (port 8889): Scans inbound MCP traffic from external AI assistants.
The chart pins Pipelock 3.4.0 by tag and multi-architecture image digest. Read the Pipelock release notes before overriding that pin.

Enabling Pipelock

This creates a separate Deployment, Service, and ConfigMap. The chart auto-injects HTTPS_PROXY, HTTP_PROXY, and NO_PROXY into web and worker pods.

Request body scanning

Request body scanning covers cleartext HTTP, reverse-proxy, and WebSocket bodies. HTTPS tunnel bodies remain opaque without TLS interception. Enabled by default with action: warn. Review findings in logs before switching to action: block.

Health watchdog

The wedge-detection watchdog returns 503 on /health when a subsystem heartbeat goes stale. It is enabled by default. Use exposeSubsystems: true to add per-subsystem detail to the health payload.

Signed action receipts

Pipelock can write hash-chained, Ed25519-signed receipts for proxied decisions. Recording is inert until you mount both a storage volume and a signing key. Generate a key and create a secret:
If you do not have the pipelock binary installed, generate the key with the pinned image:
Example Helm values using an existing PVC named sure-pipelock-evidence:
Keep requireReceipts: false until you confirm receipts are being written. When set to true, allow-path requests are blocked if Pipelock cannot sign or write the receipt.

Validating your config

Pipelock includes CLI tools for config validation and deployment diagnostics. Run them from the Pipelock container or using the pinned image locally:
In Kubernetes, run these against the running Pipelock pod:

Require Pipelock for external assistants

By default, the chart rejects an external AI assistant deployment without Pipelock:
helm template and helm install fail when rails.externalAssistant.enabled=true and pipelock.enabled=false. Set requireForExternalAssistant: false only when you accept direct external-assistant traffic without scanning.

Exposing the MCP proxy externally

Enable the Pipelock Ingress so external agents can reach the MCP reverse proxy:
Or port-forward for testing:
For full Pipelock configuration options, see Self-hosting with Docker and the pipelock.example.yaml reference file in the Sure repository.

Getting help

If you find bugs or have feature requests: