Getting started on Helm§
TL;DR§
- Official Helm chart: warp-tech/warpgate/helm/warpgate
- OCI:
oci://ghcr.io/warp-tech/helm-charts/warpgate - Image name:
ghcr.io/warp-tech/warpgate - Image in the GHCR: https://github.com/warp-tech/warpgate/pkgs/container/warpgate
- Persistent volume required:
/data(when using SQLite) - Ports:
2222(SSH),8888(HTTP),33306(MySQL),55432(PostgreSQL), optionally Kubernetes (setup.kubernetes/service.ports.kubernetes) - Tags:
latest(stable),X.Y,X.Y.Z
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