Kubernetes
The Helm chart runs the API, the worker and the dashboard. You supply PostgreSQL and Redis.
Prerequisites
Section titled “Prerequisites”- Kubernetes 1.24+ and Helm 3.8+
- PostgreSQL 16+ and Redis 7+, managed or self-run.
postgres:16-alpineandredis:7-alpineare the images the project tests against.
Install
Section titled “Install”-
Create the namespace and secrets
Terminal window kubectl create namespace railhookkubectl -n railhook create secret generic railhook-secrets \--from-literal=encryption-key="$(openssl rand -base64 32)" \--from-literal=encryption-salt="$(openssl rand -base64 24)" \--from-literal=jwt-secret="$(openssl rand -base64 64)"kubectl -n railhook create secret generic railhook-postgresql-secret \--from-literal=password="$DB_PASSWORD"kubectl -n railhook create secret generic railhook-redis-secret \--from-literal=password="$REDIS_PASSWORD"All three keys in
railhook-secretsare required; without them the API and worker pods crash-loop. -
Write a values file
values-mycompany.yaml postgresql:external:host: postgres.example.comport: 5432database: railhookusername: webhook_userexistingSecret: railhook-postgresql-secretredis:external:host: redis.example.comport: 6379existingSecret: railhook-redis-secretui:ingress:hosts:- host: hooks.example.compaths:- path: /pathType: PrefixWith
app.baseUrlempty, the chart takes the public URL from the first ingress host. Set it if Railhook is reached by another name. -
Install the chart
The chart is on GHCR for every release; its version is the release number without the
v:Terminal window helm install railhook oci://ghcr.io/vadymkykalo/charts/railhook \--version <version> -n railhook -f values-mycompany.yaml -
Check it
Terminal window kubectl -n railhook get podskubectl -n railhook logs -l app.kubernetes.io/component=api --tail=20
api.env.APP_ENV defaults to production. With email off, accounts are created already verified and nobody can be invited. To turn it on:
email: enabled: true from: noreply@hooks.example.com smtp: host: smtp.example.com port: 587 username: railhook@example.com auth: true starttls: true existingSecret: railhook-smtp-secret # key: smtp-passwordFor production defaults (more replicas, autoscaling, disruption budgets, network policies, email on), clone the repository and add -f deploy/helm/railhook/values-production.yaml.
How it behaves
Section titled “How it behaves”| Topic | Behaviour |
|---|---|
| Migrations | Run inside the API pod at startup. Replicas starting together wait on a PostgreSQL advisory lock, so each migration is applied once. A worker pod from a new release waits up to 15 minutes for them before it starts, and its startup probe allows that wait |
| Workers | Each worker claims due deliveries from PostgreSQL with FOR UPDATE SKIP LOCKED, so added worker replicas share the work without other coordination. A claim that is not finished within WEBHOOK_CLAIM_TIMEOUT_SECONDS (300 by default) can be claimed by another worker |
| Backups | backup.enabled: true adds a CronJob that writes pg_dump files to a PVC and prunes old ones |
| Metrics | On the named management port (8082 for the API, 8081 for the worker), never published outside the cluster |
Upgrade
Section titled “Upgrade”helm upgrade railhook oci://ghcr.io/vadymkykalo/charts/railhook --version <version> -n railhook -f values-mycompany.yamlTake a database backup first. helm rollback returns the chart and the images, not the schema.
Uninstall
Section titled “Uninstall”helm uninstall railhook -n railhook