Deploy to Your Kubernetes Cluster
A team environment uses the same Helm chart as the Quickstart. What changes is who provides three things the Quickstart fakes or bundles: the identity provider, the data stores and the secrets.
This works on any recent Kubernetes cluster: Amazon EKS, Azure AKS, Google GKE, or one you run yourself. The charts contain no cloud-specific code. AWS additionally has a ready-made values profile, described below.
If you have not run the Quickstart yet, do that first on a laptop. It takes five minutes and shows you the moving parts before you make decisions about them.
What you bring
| You provide | Needed by | Notes |
|---|---|---|
| A Kubernetes cluster where you can create namespaces and custom resource definitions | Everything | Routes use the Kubernetes Gateway API. The gateway is Traefik, which the chart can install for you |
| An OIDC identity provider that supports the client-credentials grant | The gateway | Keycloak, Microsoft Entra ID, Auth0, Okta and similar. The claims that carry scopes and the tenant are configurable |
| PostgreSQL | Payment Gateway, Checkout | One database per service: payment_gateway, checkout |
| A message broker: RabbitMQ (AMQP 0-9-1) or Amazon SQS | AuditFlow | RabbitMQ self-hosted or managed; SQS needs only an IAM role for AuditFlow. See Choose a message broker |
| A Redis-compatible store (Valkey or Redis) | AuditFlow, Payment Gateway | Used for deduplication and rate limiting, not as a system of record |
| A DNS name and a TLS certificate | The gateway | Routes are served at gateway.<your-domain> |
| A place to keep secrets | Everything | Plain Kubernetes Secrets work. Every module chart can read its secrets through External Secrets Operator instead |
You do not have to bring all of it on day one. The chart can run PostgreSQL, RabbitMQ and Valkey inside the cluster, with persistent volumes, until you move them to managed services.
How the charts fit together
┌──────────────────────────────────────────────────────────────────────┐
│ install.sh · helm install labs64io/labs64io-ecosystem │
└──────────────────────────────────┬───────────────────────────────────┘
│ umbrella chart
┌─────────────┬──────────────┼──────────────┬──────────────┐
┌─────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐ ┌─────▼──────┐ ┌─────▼──────┐
│ api- │ │ authz-pdp │ │ auditflow │ │ payment- │ │ checkout · │
│ gateway │ │ (Cerbos) │ │ │ │ gateway │ │ portal │
└─────┬─────┘ └────────────┘ └─────┬──────┘ └─────┬──────┘ └────────────┘
│ Traefik + Gateway API │ RabbitMQ │ PostgreSQL · Redis
▼ ▼ ▼
your identity provider your infrastructure (or bundled for evaluation)
Deployment modes, capability requirements and the AWS reference profile are described in the Helm charts repository’s docs/reference.md.
1. Add the chart repository
helm repo add labs64io https://labs64.github.io/labs64.io-helm-charts
helm repo update
helm search repo labs64io
labs64io/labs64io-ecosystem is the umbrella chart that installs the platform. Each module is also published as a chart of its own.
2. Check your infrastructure before you install
The preflight chart runs one short job that tries each dependency from inside your cluster: a TCP connection to the broker, a PostgreSQL login, a Redis PING, an OIDC token request. It tells you about a closed firewall port or a wrong password before a service fails to start because of it.
Describe your endpoints in my-endpoints.yaml, enabling only the checks you need:
checks:
postgresql:
enabled: true
host: postgres.internal.example.com
database: postgres
existingSecret: preflight-postgres # keys: username, password
rabbitmq:
enabled: true
host: rabbitmq.internal.example.com
redis:
enabled: true
host: redis.internal.example.com
existingSecret: preflight-redis # key: password
oidc:
enabled: true
discoveryUrl: https://idp.example.com/realms/acme/.well-known/openid-configuration
existingSecret: preflight-oidc # keys: client-id, client-secret
helm install preflight labs64io/preflight -n labs64io --create-namespace -f my-endpoints.yaml
kubectl wait --for=condition=complete job/preflight -n labs64io --timeout=120s \
|| kubectl logs job/preflight -n labs64io --all-containers
helm uninstall preflight -n labs64io
The job completes only if every enabled check passes.
3. Install
Pick the route that fits how your team works.
Route A: the installer, with your identity provider
The fastest way to a first shared environment. The installer asks for your OIDC discovery URL and which modules you want, runs the data stores inside the cluster with generated passwords, and leaves the demo identity provider out.
curl -fsSL https://raw.githubusercontent.com/Labs64/labs64.io-helm-charts/master/install.sh -o install.sh
bash install.sh # choose "Install or update", then "BYO"
Or without questions, taking the default module selection:
LABS64_PROFILE=byo \
LABS64_OIDC_DISCOVERY_URL=https://idp.example.com/realms/acme/.well-known/openid-configuration \
bash install.sh
The installer writes the Helm values it used to ./labs64.io-install/values-overrides.yaml. That file is a good starting point for Route B when you outgrow the installer. The Quickstart lists the commands for checking, stopping and removing the install.
Route B: Helm, with your own values file
Use this when values live in version control and a pipeline or a GitOps tool applies them. This example points the platform at your own data stores and identity provider. Save it as my-values.yaml:
global:
domain: example.com # routes are served at gateway.example.com
postgresql:
host: postgres.internal.example.com
rabbitmq:
host: rabbitmq.internal.example.com
redis:
host: redis.internal.example.com
# Your infrastructure replaces the bundled data stores.
postgresql:
enabled: false
rabbitmq:
enabled: false
redis:
enabled: false
api-gateway:
oidc:
discoveryUrl: https://idp.example.com/realms/acme/.well-known/openid-configuration
auditflow:
gateway:
enabled: true
env:
- name: LABS64_AUTH_AUTHZ_PDPADDRESS
value: "labs64io-authz-pdp:3593"
payment-gateway:
gateway:
enabled: true
env:
- name: LABS64_AUTH_AUTHZ_PDPADDRESS
value: "labs64io-authz-pdp:3593"
# Installs Traefik and the shared Gateway. Leave this off if you already run a
# Gateway named labs64io-gateway in the tools namespace.
traefik:
enabled: true
Keep the passwords out of that file. Put them in a second one that never reaches version control, or let External Secrets Operator supply them:
# my-secrets.yaml
secrets:
postgresqlPassword: "..."
rabbitmqPassword: "..."
redisPassword: "..."
Then install the Gateway API resource definitions, following the upstream guide, and the chart:
kubectl create namespace tools # holds the shared Gateway object
helm upgrade --install labs64io labs64io/labs64io-ecosystem \
--namespace labs64io --create-namespace \
--version <chart-version> \
-f my-values.yaml -f my-secrets.yaml
helm test labs64io -n labs64io
Three details in the example are worth knowing:
- The release name is
labs64io. The addresslabs64io-authz-pdp:3593follows from it. Without that setting, services look for a policy engine next to themselves, find none, and deny every request. - The chart refuses to install with its shipped default passwords. That check is deliberate; it is only relaxed in demo mode.
- Pin
--version. The umbrella chart version is the release number of the whole platform, so pinning it makes an environment reproducible.
helm show values labs64io/labs64io-ecosystem prints every setting. To read the example profiles that ship inside the chart:
helm pull labs64io/labs64io-ecosystem --untar
ls labs64io-ecosystem/values*.yaml # values.yaml, values.demo.yaml, values.aws.yaml
Route C: one module at a time
Every module chart installs on its own, so you can adopt a single capability and add the rest later:
helm upgrade --install auditflow labs64io/auditflow -n labs64io -f auditflow-values.yaml
Module charts bundle no data stores; you point each at yours. The Helm charts repository lists what each module needs, the routes it exposes, and a commented production example per module under overrides/<module>/values.prod-example.yaml.
AWS, Azure, Google Cloud and on-premises
The platform needs capabilities, not specific products. This is how they usually map:
| Capability | AWS | Azure | Google Cloud | Self-managed |
|---|---|---|---|---|
| Kubernetes | EKS | AKS | GKE | Any conformant cluster |
| PostgreSQL | RDS for PostgreSQL | Azure Database for PostgreSQL | Cloud SQL for PostgreSQL | Bundled, or your own |
| Redis-compatible store | ElastiCache (Valkey) | Azure Cache for Redis | Memorystore | Bundled, or your own |
| Message broker (AuditFlow) | Amazon SQS, or Amazon MQ for RabbitMQ | Bundled, or a hosted RabbitMQ | Bundled, or a hosted RabbitMQ | Bundled RabbitMQ, or your own |
| Secrets | Secrets Manager | Key Vault | Secret Manager | Kubernetes Secrets, Vault |
| Identity | Any OIDC provider | Entra ID, or any OIDC provider | Any OIDC provider | Keycloak, or any OIDC provider |
On AWS, the umbrella chart ships a reference profile, values.aws.yaml, for EKS with managed data stores, AuditFlow on Amazon SQS (through its IAM role) and secrets read from AWS Secrets Manager through External Secrets Operator. For Amazon MQ instead, set auditflow.applicationYaml.auditflow.broker.type: rabbitmq and the broker’s host. You provision the infrastructure with the tool you prefer and pass its coordinates in a second values file; the header of values.aws.yaml lists exactly which ones. On this profile the gateway is installed first, as a release of its own:
helm upgrade --install labs64io labs64io/labs64io-ecosystem -n labs64io \
-f labs64io-ecosystem/values.aws.yaml -f my-environment.yaml
On Azure and Google Cloud, use Route A or Route B. To read secrets from Key Vault or Secret Manager, install External Secrets Operator, create a ClusterSecretStore for your provider, and set externalSecrets.enabled: true on each module.
On any cloud, two things catch people out:
- The bundled data stores need a default StorageClass. Some managed clusters, newer EKS clusters among them, come without one marked as default; check with
kubectl get storageclass. The installer warns you when it is missing. Without one, the database pods stayPending. - A load balancer created for the gateway is usually public. Decide whether it should be before you install, and never expose an install that runs the demo identity provider.
Before you go live
Treat these as deployment responsibilities. The software does not do them for you.
| Area | What to confirm |
|---|---|
| Identity | A real OIDC provider is configured, and the demo identity provider is not installed. It issues a valid token to anyone |
| TLS | The gateway is reached over HTTPS only, with TLS terminated at your load balancer or at Traefik |
| Secrets | No password sits in a values file under version control, and every generated or default password has been replaced |
| Data | PostgreSQL has backups and you have restored one. The broker’s storage is persistent |
| Network | Network policies are enabled (networkPolicy.enabled) and only the gateway is reachable from outside |
| Payments | Provider webhooks are verified before your systems act on them |
| Observability | Metrics, logs and traces reach a backend someone watches (observability.enabled), and alerts have an owner |
| Versions | The chart version is pinned per environment and upgrades are rehearsed in a non-production environment first |
Continue with Security & Compliance, Monitoring & Observability and Kubernetes & Helm Setup.