Skip to content

Configuration reference

All persistent configuration lives in dekube.yaml. This file is created on first run and preserved across re-runs. User edits are never overwritten.

This is your territory. The engine converts; the config file is where you tell it what to ignore, what to override, and what to pretend was never there. Think of it as the leash on a machine that has no business existing — short enough to control, long enough to be useful.

Full example

name: my-platform
volume_root: ./data
extensions:
  caddy:
    email: admin@example.com

distribution_version: v3.1.0
depends:
  - keycloak
  - cert-manager==0.3.0
  - trust-manager

volumes:
  data-postgresql:
    driver: local
  myapp-data:
    host_path: app
  other:
    host_path: ./custom

exclude:
  - prometheus-operator
  - meet-celery-*

replacements:
  - old: 'path_style_buckets = false'
    new: 'path_style_buckets = true'

overrides:
  redis-master:
    image: redis:7-alpine
    command: ["redis-server", "--requirepass", "$secret:redis:redis-password"]
    volumes: ["$volume_root/redis:/data"]
    environment: null

services:
  minio-init:
    image: quay.io/minio/mc:latest
    restart: on-failure
    entrypoint: ["/bin/sh", "-c"]
    command:
      - mc alias set local http://minio:9000 $secret:minio:rootUser $secret:minio:rootPassword
        && mc mb --ignore-existing local/my-bucket

Engine keys

These are the controls that let you steer the heresy — what to exclude, what to override, what to pretend doesn't exist. All documented in the engine reference; they work identically in helmfile2compose:

  • name — compose project name (auto-detected on first run)
  • volume_root — base path for PVC bind mounts (default: ./data)
  • volumes — PVC-to-volume mappings (auto-populated on first run)
  • exclude — workload names to skip (fnmatch wildcards)
  • replacements — global find/replace in env vars, ConfigMap files, and proxy upstreams
  • overrides — deep merge into generated services (null deletes keys). Every generated environment value gets its $ doubled ($$) so compose doesn't interpolate it, but overrides: values stay raw — you keep ${VAR} compose interpolation there, and a $secret: reference inside an override still resolves and escapes correctly.
  • services — custom compose services added verbatim
  • extensions — per-extension config (Caddy email/TLS, enable/disable)
  • ingress_types — custom ingressClassName → rewriter mapping
  • disable_ingress — skip reverse proxy generation
  • network — external compose network override

Upgrading: $ escaping changed

If you were hand-escaping $$ in chart values or replacements: to work around passwords getting mangled by compose interpolation, remove it now — you'd otherwise get $$$$. Conversely, a ${VAR} you meant for compose interpolation but that arrives through chart values or replacements: is now taken literally; move it into overrides:, which stays raw.

Upgrading past helmfile2compose v3.4.0

Regenerating with a newer release changes a few things you can see: env now wins over envFrom; every $ in container commands is escaped (a ${VAR} meant for compose goes in overrides:); mounts with items move to configmaps/<name>_<hash>/; PVC subPath is honoured (data already at the volume root keeps the old mount, with a warning); an extension that fails to load stops the run (exit 1). A LoadBalancer Service publishes its port instead of its nodePort. fix-permissions now emulates fsGroup (group ownership, g+rwX, setgid dirs, group_add). A server-ca Secret missing from the manifests keeps its mount with a warning — provide ./secrets/<name>/ca.crt. With the nginx or traefik rewriter loaded, classless Ingresses carrying their annotations now go to them instead of HAProxy. The nginx and traefik rewriters now warn about the catch-alls they skip, and nginx use-regex paths become prefix matches (a regex that isn't a plain prefix wildcard falls back to its literal prefix, with a warning). httpGet healthchecks fall back from wget to curl to bash's /dev/tcp. servicemonitor (new job_name, so a new job label; namespaceSelector), cnpg (<cluster>-superuser is only published with enableSuperuserAccess: true, CloudNativePG's default being false) and fake-apiserver users: see the full list.

See the full engine configuration reference for detailed descriptions, examples, placeholders ($secret:, $volume_root), and legacy key migration.

Distribution-specific keys

These keys are for the package manager, not the engine. The engine doesn't care what version it is; the manager cares so you don't wake up to a breaking change on a Tuesday morning.

distribution_version

Pin the distribution version for dekube-manager.

distribution_version: v3.1.0

core_version is accepted as a backwards-compatible alias.

distribution

Select which distribution dekube-manager installs. Default: helmfile2compose. Use engine for the bare engine (dekube.py).

distribution: helmfile2compose

depends

List of dekube extensions required by this project. dekube-manager reads this list and installs them automatically.

depends:
  - keycloak
  - cert-manager==0.3.0
  - trust-manager

Bare names pull the latest release. Pin with ==version for reproducibility (recommended — see Your project). Tags can be moved; for an immutable pin, use a commit SHA (keycloak==6a556e2). An extension the distribution already bundles is skipped, unless you pin it — the pinned copy then overrides the bundled one. An extension that declares a min_engine newer than the engine being installed is refused (checked for distribution: engine only). Downloads are retried on connection errors, timeouts and HTTP 5xx (up to three retries, 1s/2s/4s apart), never on a 4xx such as a 404, and each file is written to a temp file then renamed into place, so an interrupted install doesn't leave a truncated extension for the next run to reuse.

See dekube-manager — declarative dependencies for override behavior and details.