Configuration¶
This page covers AKKO's secrets management, TLS setup, deployment profiles, resource requirements, and common configuration pitfalls.
Secrets and Configuration¶
All secrets are managed via Kubernetes Secrets, auto-generated by Helm templates
from global.auth.* values. For development, deterministic passwords are set in
helm/examples/values-dev.yaml.
# View all AKKO secrets in the cluster
kubectl get secrets -n akko
# Inspect a specific secret
kubectl get secret akko-secrets -n akko -o jsonpath='{.data}' | jq
Never commit secrets
The following paths are gitignored and must never be committed:
traefik/certs/-- TLS private key and certificate- Helm values files containing production passwords
Key Values¶
These values are configured in your Helm values file (e.g., helm/examples/values-dev.yaml)
under global.auth.* and injected as Kubernetes Secrets:
| Helm Value Path | Purpose | Default |
|---|---|---|
global.domain |
Base domain for all *.domain routing |
akko.local |
global.auth.postgresPassword |
PostgreSQL superuser password | random |
global.auth.postgresAkkoPassword |
akko application user password |
random |
global.auth.minioRootUser / minioRootPassword |
object storage (S3) admin credentials | akko-admin / random |
global.auth.keycloakAdminPassword |
Keycloak admin console password | random |
global.auth.keycloakDbPassword |
Keycloak PostgreSQL user password | random |
global.auth.kcClientSecret* |
OAuth2 client secrets (JupyterHub, Superset, Airflow, Dashboards, oauth2-proxy, OpenMetadata) | random hex |
global.auth.polarisRootSecret |
Apache Polaris bootstrap credential | random hex |
global.auth.supersetSecretKey |
Superset Flask secret key | random hex |
global.auth.supersetAdminPassword |
Superset admin password | random |
global.auth.airflowAdminPassword |
Airflow admin password | random |
global.auth.airflowFernetKey |
Airflow Fernet encryption key | random |
global.auth.grafanaAdminPassword |
Dashboards admin password | random |
global.auth.jupyterhubSecretToken |
JupyterHub proxy auth token | random hex |
akko-ollama.model |
Default Ollama LLM model | qwen2.5:3b |
global.auth.omAirflowPassword |
OpenMetadata ingestion Airflow password | random |
global.auth.omIngestionBotJwt |
OpenMetadata bot JWT (must be replaced after first start) | placeholder |
Regenerating Secrets¶
To rotate secrets in a Kubernetes deployment, update the values in your Helm values file and run a Helm upgrade:
helm upgrade akko helm/akko/ -n akko \
-f helm/examples/values-dev.yaml \
--set global.auth.postgresPassword=NEW_PASSWORD \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
PostgreSQL password persistence
PostgreSQL stores passwords in its persistent volume. If you change secret values in Helm, the new passwords will not take effect for existing database users. You must manually update them:
kubectl exec -n akko deploy/akko-postgresql -- psql -U postgres -c \
"ALTER USER akko WITH PASSWORD 'new-password';"
This applies to all database users: postgres, akko, keycloak_user.
Custom Domain¶
By default, AKKO uses the akko.local domain (e.g., lab.akko.local,
bi.akko.local). This is configurable via global.domain in Helm values.
To use a custom domain:
-
Set the domain in your Helm values override:
-
Deploy or upgrade:
-
Ensure DNS resolves
*.akko.example.comto your cluster's ingress IP.
Inter-service communication
All inter-service communication uses Kubernetes service DNS names
(e.g., akko-akko-keycloak:8080, akko-postgresql, akko-minio:9000),
never external domain URLs.
TLS Certificates¶
Self-signed certificates are generated automatically by scripts/generate-certs.sh:
The certificate covers *.akko.local (wildcard SAN) by default. If you use a
custom domain, regenerate the certs after changing global.domain.
Safari and Self-Signed Certs¶
Safari requires manual trust for self-signed certificates:
- Open Keychain Access
- Drag
traefik/certs/akko.crtinto the System keychain - Double-click the certificate, expand Trust, set to Always Trust
- Restart Safari
Chrome and Firefox will show a warning but allow you to proceed.
Deployment Profiles¶
AKKO uses Helm sub-chart toggles to manage optional heavyweight services.
Each sub-chart can be enabled or disabled independently in your values.yaml.
Default Profile (Core)¶
helm install akko helm/akko/ -n akko --create-namespace \
-f helm/examples/values-dev.yaml \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
This deploys ~20 core services: Traefik, PostgreSQL, object storage, Polaris, Trino, Spark, JupyterHub, Superset, Airflow, Keycloak, Dashboards, Prometheus, Ollama, oauth2-proxy, cockpit, AKKO Docs, and init jobs.
Governance Profile¶
Enable OpenMetadata and OpenSearch in your values file:
Then deploy:
helm upgrade akko helm/akko/ -n akko \
-f helm/examples/values-dev.yaml \
-f values-governance.yaml \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
Or use --set flags directly:
helm upgrade akko helm/akko/ -n akko \
-f helm/examples/values-dev.yaml \
--set openmetadata.enabled=true \
--set akko-opensearch.enabled=true \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
Adds OpenMetadata (server) and OpenSearch. These services are memory-intensive and require additional cluster resources.
Enterprise Profile (directory service)¶
Enable directory service for enterprise LDAP directory integration:
helm upgrade akko helm/akko/ -n akko \
-f helm/examples/values-dev.yaml \
--set akko-lldap.enabled=true \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
Resource Requirements¶
| Profile | Minimum Cluster RAM | Recommended |
|---|---|---|
| Default (core) | 8 GB | 10 GB |
| Governance | 16 GB | 20 GB |
OpenMetadata + OpenSearch OOM
With less than 16 GB allocated to the cluster (or Docker Desktop for k3d), the governance profile services will crash in a restart loop. OpenSearch alone requires ~1 GB (heap + native memory) and will fail at 768 MB.
Rebuilding Custom Images¶
AKKO builds custom container images locally. After modifying their Dockerfiles, you must rebuild and push to the local registry:
# Rebuild all custom images and push to k3d registry:
bash helm/scripts/build-images.sh
# Then upgrade:
helm upgrade akko helm/akko/ -n akko -f helm/examples/values-dev.yaml \
--set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json
Pods use imagePullPolicy: Always in dev
In k3d dev mode, custom images use pullPolicy: Always so pods
automatically pick up newly pushed images on restart. To trigger a
rollout after pushing new images:
Version Pinning¶
Every container image uses an explicit version tag. There are
zero latest tags in the Helm chart. This ensures reproducible deployments
and makes it clear exactly which versions are running.
The cockpit Tech Stack display is generated dynamically by scripts/generate-versions.sh,
which writes branding/cockpit/versions.json.
Startup Sequence¶
The recommended way to start AKKO is through the deploy script:
This script performs the following steps in order:
- Create k3d cluster -- creates the k3d cluster with a local registry (skips if it already exists)
- Generate TLS certs -- runs
generate-certs.sh(skips if certs exist) - Build custom images -- builds and pushes
akko-postgres,akko-spark,akko-notebook,akko-cockpitto the k3d registry - Generate versions manifest -- runs
generate-versions.sh - Deploy with Helm -- runs
helm install akko helm/akko/ -n akko --create-namespace -f helm/examples/values-dev.yaml --set-file akko-keycloak.realm.data=helm/examples/realm-akko-k3d.json - Print URLs -- displays all service URLs
Init jobs (postgres-init, polaris-init, minio-init, superset-init) run
automatically as Kubernetes init containers and are idempotent -- they create
databases, catalogs, buckets, and dashboards only if they do not already exist.