GitHub Warpgate for Business →

Getting started on Helm§

The Helm chart is community-maintained

TL;DR§

Prerequisites§

  • Kubernetes cluster (1.19+)
  • Helm 3.x installed
  • kubectl configured to access your cluster

Quick Start§

Install from Official Chart§

The official Helm chart is available in the Warpgate repository and as an OCI image. Create a minimal values.yaml file specifying the version:

image:
  tag: "0.28.6"

The chart's default tag is the release it was published with; pin a specific tag so that you control the version.

Then install:

helm install warpgate oci://ghcr.io/warp-tech/helm-charts/warpgate \
  --namespace warpgate \
  --create-namespace \
  --values values.yaml

Automatic Setup§

Setup runs in an init container on every pod start (chart v0.2.0+, needs Warpgate v0.30+). On an empty volume it generates the config file and a self-signed certificate; on an empty database it creates the admin user. A volume and database that are already set up are left untouched. Create a secret with the admin password:

kubectl create secret generic warpgate-secret \
  --from-literal=adminPassword='your-secure-password' \
  --namespace warpgate

Then install with setup enabled:

helm install warpgate oci://ghcr.io/warp-tech/helm-charts/warpgate \
  --namespace warpgate \
  --create-namespace \
  --set setup.enabled=true \
  --set data.pvc.enabled=true \
  --set setup.envFromSecret.WARPGATE_ADMIN_PASSWORD=warpgate-secret/adminPassword \
  --values values.yaml

Configuration§

For the complete list of available configuration options, see the full Helm values file.

Basic Values§

Create a values.yaml file to customize your deployment:

image:
  repository: ghcr.io/warp-tech/warpgate
  tag: "0.28.6"
  pullPolicy: IfNotPresent

# Automatic setup configuration
setup:
  enabled: true
  envFromSecret:
    WARPGATE_ADMIN_PASSWORD: "warpgate-secret/adminPassword"

  # Ports to expose (0 = protocol disabled)
  ssh: 2222
  http: 8888
  mysql: 33306
  pgsql: 55432
  kubernetes: 0

  # Optional: External database
  # databaseUrl: "postgres://user:password@postgres-service:5432/warpgate"

# Persistent storage
data:
  pvc:
    enabled: true
    template:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

# Service configuration
service:
  type: ClusterIP
  ports:
    ssh: 2222
    http: 8888
    mysql: 33306
    pgsql: 55432

# Resource limits
resources:
  requests:
    memory: "256Mi"
    cpu: "250m"
  limits:
    memory: "512Mi"
    cpu: "500m"

Install with custom values:

helm install warpgate oci://ghcr.io/warp-tech/helm-charts/warpgate \
  --namespace warpgate \
  --create-namespace \
  --values values.yaml

Persistent Storage§

Warpgate requires persistent storage when using the built-in SQLite database. The chart supports both PersistentVolumeClaim and emptyDir:

data:
  pvc:
    enabled: true  # Use PVC for persistence
    claimName: ""  # Use existing PVC (optional)
    template:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "fast-ssd"
      resources:
        requests:
          storage: 10Gi

The image runs as UID 1000 and most storage drivers hand over a new volume owned by root, so set podSecurityContext.fsGroup: 1000 - otherwise setup cannot write to it.

SQLite and Replicas

replicaCount above 1 needs a shared database, see below. Otherwise the chart will fail to render.

Database§

Multiple replicas need one shared database. The chart can deploy a single-instance PostgreSQL alongside Warpgate (chart v0.1.0+):

replicaCount: 3

postgresql:
  enabled: true
  storage:
    size: 8Gi

It is a simple StatefulSet on one PVC without replication or backups. If you prefer to run your own Postgres deployment point Warpgate at it instead:

setup:
  databaseUrl: "postgres://user:password@postgres-service:5432/warpgate"

With either of those, data.pvc can stay disabled: the chart renders the config file into a ConfigMap and the TLS certificate into a Secret, so the pods have no persistent state and any of them can be replaced at any time. See Running a cluster regarding load balancing, peer addressing and encryption keys.

The bundled database's password is generated once on install. Rendering with helm template (e.g. Argo CD) has no cluster to read the secret from, so it would create a new password on every sync. Supply both secrets yourself there:

postgresql:
  enabled: true
  passwordSecret: "warpgate-db/password"

tls_cert_secret: "warpgate-tls"

Service Configuration§

For production deployments, configure the service type and ports:

service:
  type: LoadBalancer  # or NodePort, ClusterIP
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
  ports:
    ssh: 2222
    http: 8888
    mysql: 33306
    pgsql: 55432

Ingress Configuration§

Enable Ingress for HTTP access:

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: warpgate.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: warpgate-tls
      hosts:
        - warpgate.example.com

TLS Certificates§

When the chart renders the config (see Database) it also generates a self-signed certificate into a Secret and keeps it across upgrades. Set tls_cert_secret to provide your own instead.

Provide the TLS certificate via a Kubernetes secret:

kubectl create secret tls warpgate-tls \
  --cert=./tls.crt \
  --key=./tls.key \
  --namespace warpgate

Reference it in values.yaml:

tls_cert_secret: "warpgate-tls"

Recordings on S3§

For more than one replica, recordings must be stored on S3 (Config > Global parameters > Session recordings, see session recordings - the bucket needs a CORS rule for playback). To use the Automatic credentials mode with a cloud IAM role, annotate the pod's service account:

serviceAccount:
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/warpgate-recordings

Encryption at rest§

See Encrypting credentials at rest for the envFromSecret keys.

Custom Configuration§

To provide a full custom Warpgate configuration:

overrides_config: |
  # Your complete warpgate.yaml configuration here
  # Ensure ports match the service configuration

The value is rendered as a Helm template (chart v0.2.0+), so it can use expressions such as {{ .Release.Namespace }}, and a literal {{ has to be written as {{ "{{" }}.

Upgrading§

To upgrade Warpgate to a new version, bump image.tag in your values.yaml and upgrade:

helm upgrade warpgate oci://ghcr.io/warp-tech/helm-charts/warpgate \
  --namespace warpgate \
  --values values.yaml

An upgrade only rolls out new pods: setup finds the existing config and database and leaves them alone, and database migrations are run by Warpgate itself on pod start. With a PVC the old pod is stopped before the new one starts (a ReadWriteOnce volume can't be attached to both).

Chart v0.2.0 needs Warpgate v0.30 or newer and refuses to render with an older image.tag. The setup.type value is no longer used and can be removed.

Read Upgrading first - back up the database, and with several replicas expect a short window of mixed versions.

Uninstalling§

To remove Warpgate:

helm uninstall warpgate --namespace warpgate

Data Persistence

Uninstalling will retain the following: the data PVC and the bundled database's PVC together with its generated password Secret.

To throw all of it away, including the database:

kubectl delete pvc,secret -l app.kubernetes.io/instance=warpgate -n warpgate

Troubleshooting§

Check Pod Status§

kubectl get pods -n warpgate
kubectl describe pod <pod-name> -n warpgate
kubectl logs <pod-name> -n warpgate

Check setup logs§

Setup is the warpgate-setup init container of each pod. When you provide a certificate, SSH keys or a custom config, a warpgate-install-files init container copies them into /data before it:

kubectl logs <pod-name> -c warpgate-setup -n warpgate

Access Warpgate Admin UI§

Get the service endpoint:

kubectl get svc -n warpgate

If using LoadBalancer or NodePort, access the HTTP port (default 8888) in your browser.

For ClusterIP, use port-forwarding:

kubectl port-forward svc/warpgate 8888:8888 -n warpgate

Then access https://localhost:8888 in your browser.

Verify Persistent Volume§

kubectl get pvc -n warpgate
kubectl describe pvc <pvc-name> -n warpgate

Shell access§

The image has no shell. Attach a debug container to the pod instead:

kubectl debug -it <pod-name> -n warpgate --image=busybox --target=warpgate -- cat /proc/1/root/data/warpgate.yaml

Up next§


Imprint