Skip to content

Installing with Helm

This page assumes everything on the Requirements page is in place: a Kubernetes cluster, ingress-nginx, cert-manager and a database decision.

The hostnames in the examples (panel.example.com and the like) are placeholders. Replace them with your own.

Terminal window
git clone https://github.com/shftco/flowdesk-kubernetes.git
cd flowdesk-kubernetes
Terminal window
kubectl create namespace flowdesk

3. Prepare the three secrets (out of band)

Section titled “3. Prepare the three secrets (out of band)”

The chart embeds no real credential in its own templates: these three secrets are created outside the chart, by you.

The API signs and verifies session tokens with this pair. Losing it drops every session.

Terminal window
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in private.pem -pubout -out public.pem
kubectl -n flowdesk create secret generic flowdesk-jwt \
--from-file=private.pem --from-file=public.pem

The ghcr.io/shftco/flowdesk-{api,web,tracker} images are private. SHFT gives you a dedicated personal access token; you pull the images by putting that token, together with a GitHub username, into the secret below:

Terminal window
kubectl -n flowdesk create secret docker-registry ghcr-pull \
--docker-server=ghcr.io \
--docker-username=<github-username> \
--docker-password=<PAT-with-read:packages> \
--docker-email=<your-e-mail>

The database, the message queue, the token encryption key, the Keycloak client secret and the licence key all live in flowdesk-secret. The key names depend on your database and messaging choices; the example below is for PostgreSQL + RabbitMQ + Keycloak:

Terminal window
kubectl -n flowdesk create secret generic flowdesk-secret \
--from-literal=POSTGRES_PASSWORD='<a-strong-password>' \
--from-literal=CONNECTION_STRING='Host=postgres;Port=5432;Database=flowdesk;Username=flowdesk;Password=<a-strong-password>;Search Path=dbo' \
--from-literal=RABBITMQ_USER='<rabbitmq-user>' \
--from-literal=RABBITMQ_PASS='<rabbitmq-password>' \
--from-literal=TOKEN_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
--from-literal=KEYCLOAK_CLIENT_SECRET='<keycloak-client-secret>' \
--from-literal=License__Key='<the-licence-key-from-SHFT>'

Notes:

  • By default the chart installs its own PostgreSQL into your cluster (postgres.enabled: true, demo/single-replica quality). The CONNECTION_STRING example above (Host=postgres) assumes that. If you are going to use SQL Server, or point at your own managed PostgreSQL, set postgres.enabled: false in values.yaml and write CONNECTION_STRING for your own server; for the format see Configuration. The same applies to redis.enabled and rabbitmq.enabled.
  • The password in CONNECTION_STRING must be exactly the same as POSTGRES_PASSWORD. If you use SQL Server the connection string format differs; see Configuration.
  • If you use Kafka, enter KAFKA_SASL_PASSWORD instead of RABBITMQ_USER/RABBITMQ_PASS (and not even that if you are not using SASL).
  • With Application:Environment=Production, guest/guest RabbitMQ credentials are rejected by the API. Supply a real user and password.
  • The installation also works without License__Key (unlicensed, unrestricted, in a “pending” state). If you do not have the key yet you can skip that line. Details: Configuration.

Write a my-values.yaml that replaces at least the following with your own values:

api:
image:
tag: <api-version> # see Release Notes for the API version you will run
web:
image:
tag: <dashboard-version>
tracker:
image:
tag: <tracker-version>
database:
provider: PostgreSql # or SqlServer
ingress:
clusterIssuer: letsencrypt-prod
hosts:
dashboard: panel.example.com
api: api.example.com
tracker: track.example.com
auth:
authority: 'https://<your-keycloak-server>/realms/<realm>'
clientId: flowdesk-web
redirectUris:
- 'https://panel.example.com/api/auth/callback/keycloak'
secrets:
existingSecret: flowdesk-secret # the secret you created in step 3.c

Pin the image tags: leave them empty and the chart falls back to its appVersion, which can leave you running a version you did not expect. You can see which tags exist on the Release Notes page and on each repository’s GitHub Releases page.

Terminal window
helm upgrade --install flowdesk ./charts/flowdesk \
-n flowdesk --create-namespace \
-f my-values.yaml
kubectl -n flowdesk get pods -w

On first boot the API creates the database schema itself and seeds the administrator user (admin@shft.co). This can take a few minutes. The startupProbe allows roughly 5 minutes for that first boot; the pod not showing as Ready during this time is normal.

Terminal window
# Confirm the deployments came up
kubectl -n flowdesk rollout status deploy/flowdesk-api
kubectl -n flowdesk rollout status deploy/flowdesk-web
kubectl -n flowdesk rollout status deploy/flowdesk-tracker
# Confirm the certificates were issued and the hostnames are right
kubectl -n flowdesk get ingress
# API health check, should return 200
curl -s -o /dev/null -w '%{http_code}\n' https://api.example.com/health

If /health returns 200, your dashboard address opens and you can sign in through Keycloak (or whichever provider you chose), and your tracker address opens, the installation is complete.

  1. For every image tag you are about to change, read that component’s notes: Release Notes. FlowDesk is made up of four components (API, Dashboard, Tracker, Knowledge Base) and each tracks its own version independently; reading only the API’s notes is not enough.
  2. Pay attention to entries under ### Changed and ### Removed, to entries that mention a configuration key, and to entries that mention a migration.
  3. If the notes mention a migration, plan a maintenance window: schema migrations are applied automatically at API startup and are not guaranteed to be zero downtime. During a rolling update a pod still running the old version can end up incompatible with the new schema and return errors.
  4. Take a database backup; see “What a rollback covers” below.
Terminal window
helm upgrade flowdesk ./charts/flowdesk -n flowdesk -f my-values.yaml \
--set api.image.tag=v0.1.2
kubectl -n flowdesk rollout status deploy/flowdesk-api
kubectl -n flowdesk rollout undo deploy/flowdesk-api # roll back if needed

Upgrade the three components (API, Dashboard, Tracker) together; SHFT publishes their version tags as a compatible set.

What a rollback covers, and what it does not

Section titled “What a rollback covers, and what it does not”

kubectl rollout undo only returns the image the pod runs to the previous version; it does not roll back the database schema. Migrations are applied automatically at API startup and only forwards; in normal operation no down migration is run. If you return to the old image after a schema migration has run (a table rename, for example), the old code keeps querying a table or column name that no longer exists and keeps failing: rollout undo is safe only when returning to a version that contained no migration. If an upgrade that contained a migration caused trouble, the only safe path is restoring from the database backup you took before upgrading.

The installation is up; now complete authentication, licensing and environment settings from Configuration, and outgoing/incoming mail from E-mail settings.