Skip to content

windmill

Metadata

Field Value
Service windmill
Purpose Self-hosted developer platform for scripts, flows, schedules, and webhooks
Criticality Tier 1
Owner Platform owner
Clusters local
Namespace windmill
Exposure internet
Stateful yes
Backup class snapshot
RPO / RTO Daily backup target, 2 to 4 hours to restore after the backup path is validated
Last reviewed 2026-08-10

1. Service Overview

Windmill is a workflow/script automation platform. This first deployment brings up a light production-shape standalone stack on the local cluster: server, two worker groups (default and native), LSP, and a bundled Postgres. It starts empty — no jobs or flows are migrated.

Summary

If Windmill is unavailable, operators cannot author or run flows on it. No other service depends on Windmill at this stage.

Dependencies

Dependency Type Why it matters
Traefik ingress External HTTPS access to the UI and API
Postgres database Persistent Windmill state (jobs, flows, users, schedules)
local-path storage PVC provisioning for Postgres on layer7-vps1

2. Architecture Diagram

[Operator / CLI / API client]
  -> [Traefik IngressRoute]
  -> [windmill-server Deployment] (MODE=server)
       -> [windmill-postgres PVC]
  [windmill-worker-default] (MODE=worker, WORKER_GROUP=default, privileged)
  [windmill-worker-native]  (MODE=worker, WORKER_GROUP=native, NATIVE_MODE)
  [windmill-lsp]            (windmill-extra image, editor autocomplete)

All pods are pinned to the layer7-vps1 node via nodeAffinity on kubernetes.io/hostname. Full-text search (the tantivy-based indexer) is Enterprise-Edition only and is not deployed on the Community-Edition image; the server falls back to database search.

3. Deployment Specifications

Item Value
Source path windmill/base and windmill/overlays/local
Deployment model Kustomize plus Fleet bundle
Namespace windmill
Workload kind Deployments (server, 2 workers, lsp) plus Postgres StatefulSet
Images ghcr.io/windmill-labs/windmill:1.768.0, ghcr.io/windmill-labs/windmill-extra:1.768.0, postgres:16-alpine
Storage local-path, Postgres 20Gi, single-node (layer7-vps1)
Probes server HTTP GET / :8000; LSP TCP :3001; Postgres pg_isready; workers have no probe on CE (Ready when running)
Node scheduling nodeAffinity on kubernetes.io/hostname=layer7-vps1 (no custom node labels)
RBAC No dedicated RBAC; ServiceAccount token automount disabled
Config files base/kustomization.yaml, overlays/local/kustomization.yaml, fleet.yaml

Cluster mapping

Cluster Overlay path Notes
local windmill/overlays/local Current standalone deployment

4. Configuration Guide

Worker groups

Group Privileged Mode Purpose
default yes subprocess jobs (Python/Deno/bash) runs job subprocesses with PID-namespace unsharing (FAVOR_UNSHARE_PID=true)
native no in-process (NATIVE_MODE=true) lightweight in-process jobs, unprivileged

The privileged default worker is a deliberate, documented exception to the repository non-root posture: it matches the upstream Helm chart default for the non-nsjail community-edition worker group. The native worker is unprivileged.

Environment variables

Variable Source Purpose Secret?
BASE_URL ConfigMap windmill-config Public URL (https://windmill.mutana.fr) no
RUST_LOG ConfigMap windmill-config Log level (info) no
JSON_FMT ConfigMap windmill-config Structured JSON logs no
DATABASE_URL Deployment env expansion Postgres connection string, assembled as postgres://$(USER):$(PASSWORD)@windmill-postgres:5432/$(DB) yes
POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB Secret windmill-secrets Postgres bootstrap and connection values yes
MODE Deployment env server/worker/indexer no
WORKER_GROUP Deployment env default or native no
NATIVE_MODE, SLEEP_QUEUE Deployment env native worker behaviour no
FAVOR_UNSHARE_PID Deployment env PID-namespace unsharing on the default worker no

DATABASE_URL is assembled by Kubernetes environment-variable expansion, so POSTGRES_PASSWORD must be URI-safe, or plan a follow-up that stores a pre-encoded connection string in the Secret.

ConfigMaps

Resource Path Purpose
windmill-config windmill/overlays/local/windmill-configmap.yaml Non-secret runtime URL, log level, JSON logging

Secrets management

  • Secret name: windmill-secrets in namespace windmill.
  • Required keys: POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB.
  • Source of truth: manually created Kubernetes Secret from an out-of-band env file based on windmill-secrets.env.example.
  • Rotation trigger: operator-initiated rotation, incident response, or Postgres credential rotation.
  • Recovery note: recreate windmill-secrets before starting Windmill or Postgres pods.

5. Access Protocols

Path URL or endpoint Audience Auth TLS terminates at
Internal windmill-server.windmill.svc.cluster.local:8000 Cluster workloads and diagnostics namespace access plus Windmill auth none internally
External https://windmill.mutana.fr Operators, CLI, API tokens Windmill auth (UI login + API tokens) Traefik

Authelia forward auth is intentionally not placed in front of Windmill so that Windmill's own authentication, API tokens, CLI, and machine-identity flows remain direct. This matches the Infisical precedent.

6. Operations and Observability

  • Primary health indicators: server Deployment ready and GET / returning 200, default worker ready, Postgres StatefulSet ready, PVC bound.
  • Dashboards or alerts: shared cluster monitoring and ingress health.
  • Log locations: deploy/windmill-server, deploy/windmill-worker-default, deploy/windmill-worker-native, deploy/windmill-lsp, statefulset/windmill-postgres.
  • Known failure modes: missing windmill-secrets, URI-unsafe Postgres password breaking DATABASE_URL, PVC provisioning failure on layer7-vps1, server blocked on database migration, default worker failing to start without privilege.

7. Backup and Recovery Notes

  • Backup method: snapshot the Postgres PVC and preserve windmill-secrets.
  • Restore prerequisites: restored Postgres PVC data, matching Secret values, local-path availability on layer7-vps1, and the Traefik route.
  • Backup gap: a tested restore drill has not been completed yet.
  • Related runbook: ../runbooks/windmill.md

8. Release and Change Notes

  • Current deployed app version: ghcr.io/windmill-labs/windmill:1.768.0.
  • Current chart version: N/A (plain Kustomize, chart used only as architecture reference).
  • Last significant change: initial standalone local deployment with server, two worker groups, indexer, LSP, bundled Postgres, Traefik exposure, manual Secret contract, and node affinity on layer7-vps1.
  • Rollback reference: remove or revert the windmill/ Fleet path and workload manifests; preserve the Postgres PVC snapshot and Secret values for recovery.