Version v0.5.6 of the documentation is no longer actively maintained. The site that you are currently viewing is an archived snapshot. For up-to-date documentation, see the latest version.

Editions & operating modes

The two editions (Lite and Pro) and the three runtime modes (Lite · Pro · Demo) — one engine, one UI, one DAG format.

Dexaflow ships in two editions that share the same engine, the same Airflow 3.3 UI, and the same DAG format (dag.py + dexaflow.yaml): Lite (the full control plane on one host — laptop, VM, or internal server) and Pro (Helm-installed on Kubernetes). You author a DAG once and it runs on either. A third, contributor-facing Demo mode is a production-shaped reference environment used to validate UI compatibility — it is not an end-user surface.

Editions at a glance (packaging & posture)

LitePro
StatusSupported — single hostIn validation — Helm on Kubernetes (tested against GKE; pin a tag)
Installone command (curl … | sh) on one machineHelm chart on your cluster
Commanddexaflow litethe deployed control plane
Autha single local admin login (password shown once at setup)enterprise: SSO/OIDC, full RBAC, multi-tenant
Executorsa local k3d mini-cluster (real pods, requires Docker to host the cluster) or subprocess (dev-only, unsandboxed, no Docker)Kubernetes only, at scale
Deployedit + hot-reloadGitOps: dexaflow compile in CI → immutable image + dag.json
Intended uselocal, small, or light production projects on a trusted/internal networkteams and production workloads at scale
DatastoresPostgres, auto-selected (Docker postgres:16 or embedded managed); no Redis — see belowexternal managed Postgres + Redis (versions)

Runtime modes (Lite · Pro · Demo)

This is the runtime details view — exact ports, database names, cluster names, and CLI surface per mode.

Lite (dexaflow lite)Pro (in validation)Demo (contributor)
AuthReal admin login (single admin generated by dexaflow setup; password recoverable via dexaflow lite reset-password)JWT + RBAC, TLS (#58), workload identity (#56)JWT login (real)
UI markerDexaflow Lite navbar (silver edition badge)Dexaflow navbar (gold edition badge)none (instance_name: Dexaflow)
HTTP / gRPC / metrics8088 / 9099 / 9098 (distinct, coexists with Demo)8080 / 9091 / 9090 (per helm/dexaflow/values.yaml; shares Demo’s ports — not co-located on the same host)8080 / 9091 / 9090
Databaseleoflow_dev (isolated; legacy schema name preserved for upgrade-in-place safety after the Dev → Lite rename)external Postgresleoflow
Clusterk3d leoflow-dev (isolated; legacy cluster name preserved)real K8s (GKE/EKS)k3d leoflow-demo
DAG sourcelive files, hot-reloadimmutable artifact via CIfrozen artifact (compile + push)
Executork3d pods (default) or subprocess (--executor)KubernetesExecutorKubernetesExecutor

Dexaflow Lite

Lite is the whole control plane on your machine, scoped down for local use. One command installs it, dexaflow setup provisions a managed Python and a single admin, and dexaflow lite <project> serves the UI with hot-reload at http://localhost:8088 (marked Dexaflow Lite in the navbar, login enabled). Edit dags/<project>/dag.py or dexaflow.yaml, save, and it hot-reloads — fully isolated from Demo (own DB, own cluster, own ports) so there is no split brain.

Dexaflow Lite — the ETL graph running on a local cluster

  • dexaflow doctor — check the host (OS, Docker/k3d/kubectl/python3) and report the achievable executor tier.
  • dexaflow lite dags/hello — run a project (k8s executor: real k3d pods).
  • dexaflow lite --executor=subprocess dags/hello — fast host loop (no image build).
  • dexaflow db migrate|reset — manage the Lite database (Airflow-style).

It is deliberately simple, which has security implications:

Lite also includes a small built-in web editor (Monaco, with Python/YAML highlighting) so you can edit DAG projects from the browser — a Lite-only convenience; Pro teams use their own editor and the GitOps flow.

The Dev → Lite rename is a product/branding change — the internal storage names (leoflow_dev database, leoflow-dev k3d cluster) are preserved so existing installs upgrade in place.

Datastore (auto-selected), no Redis

Lite’s datastore is Postgres, chosen automatically for the host: when Docker is present it uses the postgres:16 container; when it is not, it falls back to an embedded managed Postgres (a pinned, checksum-verified relocatable build downloaded under ~/.dexaflow, on a local Unix socket) — so dexaflow lite runs on a Docker-free host with nothing to install. (Force either with --postgres docker|managed.) The Docker Postgres is started with docker compose, so auto also falls back to the managed Postgres when the Docker daemon answers but the Compose v2 plugin is not installed, and says so. An explicit --postgres docker on such a host stops with what to do: install the Compose v2 plugin, or use --postgres managed.

The managed Postgres has builds for Linux (glibc and musl) and macOS; Ubuntu 22.04 and 24.04 are tested on bare containers. It links libxml2, Kerberos, OpenSSL 3, zstd and lz4 from the host, and the musl build also links ICU 74. Desktop installs have them; on a bare container or a minimal server Lite stops before starting Postgres, names each missing library and, on Debian, Ubuntu and Alpine, prints the command that installs them. The glibc build does not use ICU, so the host’s ICU release does not matter.

Lite owns its database: it runs only on the Postgres it starts, and it does not read DEXAFLOW_DATABASE_URL (or LEOFLOW_DATABASE_URL). One exported in your shell is not passed to the Lite server, and dexaflow lite prints a note when it names another database. --no-up only skips starting the Docker Postgres when Lite’s own is already running; it does not point Lite at another database. dexaflow db reset refuses, dropping nothing, while either variable names a database other than Lite’s. To run on a Postgres of your own, use Pro.

Either way Lite needs no Redis — scheduler locks use Postgres advisory locks and XCom is stored in Postgres. The Postgres-backed XCom is durable (it survives a restart), which suits light production, and a single datastore is simpler to operate; Redis is a production-scale concern. (See ADR 0026.)

For task execution, the k3d path runs real pods and therefore requires Docker to host the cluster — but Docker is only the substrate of k3d, never an executor: Lite talks to the Kubernetes API, and a Docker-socket executor was rejected because it is equivalent to host root. subprocess runs tasks directly on the host (no Docker, no isolation) as an explicitly dev-only escape hatch. (See ADR 0027.)

Dexaflow Pro (chart-installable)

Pro is the enterprise control plane: enterprise authentication (SSO/OIDC), full role-based access control, multi-tenant isolation, the Kubernetes executor at scale, first-class observability, and the GitOps deploy flow (DAGs as immutable images + dag.json, shipped from CI). The Helm chart is Helm-installable and in active validation — tested against GKE, not yet certified for production. Pin a specific tag and read the release notes before upgrading (pre-1.0, breaking changes ship between minor versions with a migration note, ADR 0037).

Install via the Helm chart (chart-test gated, multi-arch images published per release, signed with cosign). Hardening templates ship as opt-in toggles: HPA + NetworkPolicy + ServiceMonitor; the PodDisruptionBudget turns itself on when the control plane runs more than one replica (see Control-plane HA). Runs on any K8s cluster with external Postgres + Redis.

Deployment topology (role split)

Pro can run the control plane as one process or split into two deployments by server.role (ADR 0049). Lite is always role=all. Splitting lets the internet-facing API run under least-privilege RBAC while only the scheduler holds pod-create and agent-facing rights; the two halves share nothing but Postgres.

flowchart TB
  subgraph LITE["Lite · role=all — one process"]
    ALL["dexaflow-server<br/>API + UI + scheduler<br/>+ dispatch + agent gRPC"]
  end

  subgraph PRO["Pro · role=api + role=scheduler — two deployments"]
    direction LR
    subgraph D1["Deployment: role=api (restricted)"]
      APIP["API + UI<br/>internet-facing"]
      RB1["ServiceAccount<br/>least-privilege RBAC<br/>(no pod create,<br/>no agent gRPC)"]
    end
    subgraph D2["Deployment: role=scheduler (privileged)"]
      SCHP["scheduler + dispatch<br/>reconciler + agent gRPC"]
      RB2["ServiceAccount<br/>pod create/delete<br/>+ TokenReview"]
    end
    APIP --- PGP[("Postgres<br/>shared state")]
    SCHP --- PGP
  end

See the architecture overview for how the roles sit in the whole system.

Demo (contributor reference)

The familiar, production-like environment for contributors to validate the Airflow-UI compatibility and showcase the product. It serves frozen artifacts — to change a DAG you dexaflow compile + dexaflow push. Auth is on; log in normally. Demo is the target for UI compatibility work and is referenced from the contributing guide.

Which one? (recommendation)

Choose by deployment, not by feature checklist:

  • Choose Lite when you run on one machine (laptop, a small VM, an internal box), want a one-command, Docker-free install, and your workload is local development, a small project, or light production on a trusted/internal network. Lite goes from zero-dependency (subprocess) to real pod-per-task (k3d) on the same binary, with a durable embedded Postgres.
  • Choose Pro when you need Kubernetes at scale, a team (SSO/OIDC + RBAC + multi-tenant), high XCom throughput, external managed datastores, and the GitOps deploy flow — delivered as the Helm chart.

Rule of thumb: if it fits on one host and the network is trusted, Lite is enough; when you need a cluster, multiple users, or scale, that’s Pro. Because both editions share the DAG format, the engine, and the UI, a DAG authored on Lite carries straight over to Pro unchanged — going from a single host to a cluster is a deployment change, not a DAG rewrite.