From 3e9f636aae60a6031d10a0155cd7f325ced8aaa7 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Thu, 4 Jun 2026 15:23:13 +0000 Subject: [PATCH] docs(docker): enable # docker on the default worker (full image + /dev/fuse) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the dedicated windmill_worker_docker group example with guidance on the default worker: since # docker scripts are tagged "bash" they already run there, so the only requirements are a *-full image (ships podman) and the /dev/fuse device — no dedicated group or custom tag. Also note the *-full image's bundled runtimes (Java, .NET, Ruby, R, Rust, Ansible, Nushell; Oracle/Kerberos in EE). Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 15 +++++++----- docker-compose.yml | 60 +++++++++++++++++++--------------------------- 2 files changed, 33 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index c3188335f6..90c6b90ce3 100644 --- a/README.md +++ b/README.md @@ -208,12 +208,15 @@ docker compose up -d Go to http://localhost - default credentials: `admin@windmill.dev` / `changeme` > [!NOTE] -> To run `# docker` scripts (bash scripts with the `# docker` annotation): on a worker -> with **no Docker daemon provided** (no `DOCKER_HOST`, no mounted `/var/run/docker.sock`), -> Windmill automatically runs each docker job in its own ephemeral **rootless podman**, -> torn down with the job — no privileged daemon, no host socket, scripts unchanged. Just -> use a `*-full` image (ships podman) and tag your docker scripts to a dedicated worker -> group; see the commented `windmill_worker_docker` service in +> To run `# docker` scripts (bash scripts with the `# docker` annotation): these run +> on the default worker like any bash job. Just give that worker a `*-full` image +> (ships podman) and the `/dev/fuse` device. On a worker with **no Docker daemon +> provided** (no `DOCKER_HOST`, no mounted `/var/run/docker.sock`), Windmill then runs +> each docker job in its own ephemeral **rootless podman**, torn down with the job — no +> privileged daemon, no host socket, scripts unchanged. The `*-full` image is also the +> batteries-included runtime — on top of the base (TS/Bun/Deno, Python, Go) it adds +> Java, .NET, Ruby, R, Rust, Ansible, and Nushell (plus Oracle/Kerberos in EE). See the +> default `windmill_worker` notes in > [docker-compose.yml](./docker-compose.yml). To use an external/host Docker daemon > instead (legacy), provide `DOCKER_HOST` or mount `/var/run/docker.sock`. diff --git a/docker-compose.yml b/docker-compose.yml index a58e5172df..5acd1c8867 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -80,44 +80,32 @@ services: logging: *default-logging - ## To run `# docker` scripts (bash scripts with the `# docker` annotation), add a - ## dedicated worker group with the rootless podman container runtime. Each docker - ## job gets its OWN ephemeral rootless podman, torn down with the job, so no - ## container outlives it — no privileged dind sidecar and no host Docker socket. - ## Your scripts (docker pull / docker run --name $WM_JOB_ID ...) are unchanged. + ## Running `# docker` scripts (bash scripts with the `# docker` annotation that + ## do `docker pull` / `docker run --name $WM_JOB_ID ...`): these run on the + ## default worker like any bash job — no dedicated worker group or custom tag. + ## To enable them, give the worker above two things: + ## 1. a *-full image (ships podman + the docker CLI): + ## image: ghcr.io/windmill-labs/windmill-full:main # windmill-ee-full:main for EE + ## 2. the /dev/fuse device (rootless fuse-overlayfs storage): + ## devices: + ## - /dev/fuse + ## Each docker job then spins up its OWN ephemeral rootless podman, torn down + ## with the job — no privileged dind sidecar and no host Docker socket. Your + ## scripts are unchanged. ## - ## ROUTING: `# docker` scripts are tagged by language ("bash"), so to send them - ## here set the script's custom tag to "docker" (the tag this group listens on via - ## WORKER_TAGS below). Non-docker jobs keep running on the default worker group. + ## The *-full image is also the batteries-included runtime: on top of the base + ## (TypeScript/Bun/Deno, Python, Go, bash) it adds Java, .NET (C#), Ruby, R, + ## Rust, Ansible, and Nushell — plus the Oracle DB client and Kerberos in EE — + ## so the same worker can run those jobs too. ## - ## Requires a *-full image (ships podman). Runs as a non-root user so a container - ## escape lands as an unprivileged user. podman runs inside the worker container, - ## so the container needs privileged + /dev/fuse; full memory monitoring needs - ## cgroup v2 delegation from the host (else mem_peak may be 0). For the strongest - ## isolation, run this group on a dedicated host/node. - # windmill_worker_docker: - # image: ghcr.io/windmill-labs/windmill-full:main # windmill-ee-full:main for EE - # pull_policy: always - # user: "1000:1000" # rootless: escapes land as an unprivileged user - # privileged: true # required for rootless podman-in-container (userns + mounts) - # restart: unless-stopped - # environment: - # - DATABASE_URL=${DATABASE_URL} - # - MODE=worker - # - WORKER_GROUP=docker - # - WORKER_TAGS=docker # only serve jobs tagged "docker" (set that tag on your docker scripts) - # # No DOCKER_HOST / docker socket is provided, so docker jobs automatically use - # # the bundled rootless podman (per job). Provide a DOCKER_HOST or mount - # # /var/run/docker.sock instead to use an external/host Docker daemon (legacy). - # depends_on: - # db: - # condition: service_healthy - # devices: - # - /dev/fuse # for fuse-overlayfs storage - # volumes: - # - worker_dependency_cache:/tmp/windmill/cache - # - worker_logs:/tmp/windmill/logs - # logging: *default-logging + ## Hardening: the worker above runs as root (rootful podman, still works). For + ## the rootless benefit (a container escape lands as an unprivileged user) add + ## `user: "1000:1000"` and `- HOME=/tmp`. Full memory monitoring (mem_peak) + ## needs cgroup v2 delegation from the host. For the strongest isolation, run + ## docker workloads on a dedicated host/node. + ## + ## Legacy: to use an external/host Docker daemon instead of the bundled podman, + ## set DOCKER_HOST or mount /var/run/docker.sock into the worker. ## This worker is specialized for "native" jobs. Native jobs run in-process and thus are much more lightweight than other jobs windmill_worker_native: