diff --git a/JOURNAL.md b/JOURNAL.md index ce5479b..c24e9a5 100644 --- a/JOURNAL.md +++ b/JOURNAL.md @@ -723,6 +723,55 @@ Dockerfile --- +### 9. Windmill (Automation) ✅ +**Date**: 2026-07-30 +**Application**: Windmill — open-source workflow automation / internal-apps platform +**Package Size**: ~2GB (bundles Python, Go, Rust runtimes for user scripts) +**Port**: 8000 +**Addons**: localstorage, postgresql + +**Key Learnings**: +- Official-image wrapper around `ghcr.io/windmill-labs/windmill:1.514.1` +- **PostgreSQL-only**: Windmill uses Postgres `LISTEN/NOTIFY` for job queuing, + so **no Redis is required** (unlike NetBox). This makes it a clean Cloudron fit. +- Single-container **server mode** embeds a default worker (no separate worker + container needed) +- `DATABASE_URL` is composed at runtime in `start.sh` from the Cloudron + PostgreSQL addon env vars — Windmill has no per-var DB config, just the URI +- **OIDC/SAML are configured in the in-app Admin Settings UI** (persisted to + the DB), not via environment variables — so the package supports OIDC but + the admin enables it post-install + +**Build Process**: +- Base: `ghcr.io/windmill-labs/windmill:1.514.1` (pinned, verified) +- Image config inspected (no full pull) via `docker buildx imagetools inspect` + to confirm WorkingDir `/usr/src/app`, binary `windmill` on PATH, port 8000 +- `start.sh` waits for Postgres (bash `/dev/tcp`, no `pg_isready` dependency), + then `exec windmill` +- Logo extracted from inside the image (`/static_frontend/logo.svg`) and + converted to PNG with ImageMagick + +**Validation (full integration test)**: +- `docker build` → success +- Ran a throwaway `postgres:14-alpine` + the windmill image on a shared network +- Migrations completed (`v2 finalization step successfully applied`) +- `GET /api/version` → `CE v1.514.1`, HTTP 200 ✅ +- Non-fatal: logs an embeddings-DB error when no AI API key is set (expected; + Windmill runs fine without AI embeddings) + +**Files Created**: +- Dockerfile (official-image wrapper) +- CloudronManifest.json (port 8000, postgresql + localstorage, healthCheckPath /api/version, 2GB memory) +- start.sh (DB wait + DATABASE_URL composition) — committed executable +- README.md (OIDC post-install setup, features, addons) +- CHANGELOG.md +- .env.example +- logo.png (brand icon from upstream image, SVG→PNG) + +**Commit**: `feat: add Windmill Cloudron package (Automation)` + +--- + ## Packaging Pattern: Download Pre-Compiled Binaries ### When to Use diff --git a/Package-Workspace/Automation/windmill/.env.example b/Package-Workspace/Automation/windmill/.env.example new file mode 100644 index 0000000..4051c83 --- /dev/null +++ b/Package-Workspace/Automation/windmill/.env.example @@ -0,0 +1,5 @@ +# Windmill derives DATABASE_URL from the Cloudron PostgreSQL addon at runtime. +# Only MODE is overridable; the default (server) embeds a worker. + +# Run mode: server (server + default worker), worker, or indexer. +MODE=server diff --git a/Package-Workspace/Automation/windmill/CHANGELOG.md b/Package-Workspace/Automation/windmill/CHANGELOG.md new file mode 100644 index 0000000..9983044 --- /dev/null +++ b/Package-Workspace/Automation/windmill/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +## 1.514.1 — Initial Cloudron package + +- First Cloudron package for Windmill +- Wraps the official `ghcr.io/windmill-labs/windmill:1.514.1` image +- Single-container server mode (embedded default worker) +- PostgreSQL-backed via the Cloudron `postgresql` addon (no Redis required) +- `start.sh` derives `DATABASE_URL` from Cloudron env and waits for the DB +- HTTP port 8000, health check on `/api/version` +- OIDC/SAML supported via the in-app Admin Settings UI (post-install config) diff --git a/Package-Workspace/Automation/windmill/CloudronManifest.json b/Package-Workspace/Automation/windmill/CloudronManifest.json new file mode 100644 index 0000000..96eacf5 --- /dev/null +++ b/Package-Workspace/Automation/windmill/CloudronManifest.json @@ -0,0 +1,25 @@ +{ + "version": 1, + "manifestVersion": 2, + "type": "app", + "id": "io.cloudron.windmill", + "title": "Windmill", + "description": "Windmill is an open-source workflow automation platform. Turn scripts (Python, JS/TS, Go, Bash, SQL, PHP, Rust, PowerShell) into sharable HTTP endpoints and background jobs, chain them into flows, and build internal apps on top. Uses PostgreSQL for state and queuing (no Redis required).", + "author": "Windmill Labs", + "website": "https://www.windmill.dev", + "contactEmail": "cloudron@tsys.dev", + "tagline": "Open-source workflow automation and internal apps platform", + "version": "1.514.1", + "healthCheckPath": "/api/version", + "httpPort": 8000, + "memoryLimit": 2048, + "addons": { + "localstorage": true, + "postgresql": { + "version": "14" + } + }, + "mediaLinks": [], + "changelog": "Initial Cloudron package for Windmill. PostgreSQL-backed (no Redis); single-container server mode with embedded worker. OIDC/SAML supported via the in-app Admin Settings.", + "icon": "file://logo.png" +} diff --git a/Package-Workspace/Automation/windmill/Dockerfile b/Package-Workspace/Automation/windmill/Dockerfile new file mode 100644 index 0000000..42f6ecb --- /dev/null +++ b/Package-Workspace/Automation/windmill/Dockerfile @@ -0,0 +1,25 @@ +# Windmill Cloudron Package +# +# Windmill is an open-source workflow automation platform (scripts, flows, +# apps, schedules) that turns scripts into sharable HTTP endpoints and +# background jobs. The server embeds a default worker for single-container use. +# +# Upstream image: ghcr.io/windmill-labs/windmill:1.514.1 +# - WorkingDir /usr/src/app, binary `windmill` on PATH, listens on 8000 +# - Requires PostgreSQL (job queue uses Postgres LISTEN/NOTIFY; NO Redis) +# - Auto-runs SQL migrations on startup +# +# Authentication: Windmill supports OIDC and SAML natively. OIDC is configured +# in the Admin Settings UI (persisted in the database), not via env vars. See +# README.md for the post-install OIDC setup steps. +FROM ghcr.io/windmill-labs/windmill:1.514.1 + +ENV MODE=server + +# start.sh builds DATABASE_URL from the Cloudron PostgreSQL addon, waits for +# the DB, then execs the windmill server. Made executable on the host. +COPY start.sh /app/start.sh + +EXPOSE 8000 + +CMD ["/bin/bash", "/app/start.sh"] diff --git a/Package-Workspace/Automation/windmill/README.md b/Package-Workspace/Automation/windmill/README.md new file mode 100644 index 0000000..2bb63a8 --- /dev/null +++ b/Package-Workspace/Automation/windmill/README.md @@ -0,0 +1,78 @@ +# Windmill Cloudron Package + +## Description + +Windmill is an open-source developer platform to turn scripts into workflows +and internal apps. Write scripts in Python, JavaScript/TypeScript, Go, Bash, +SQL, PHP, Rust, PowerShell, or Deno; Windmill turns them into sharable HTTP +endpoints, cron-scheduled jobs, and steps in visual **Flows**. It also +generates internal apps from those flows. + +This package wraps the official `ghcr.io/windmill-labs/windmill` image in +single-container **server mode** (the server embeds a default worker, so no +separate worker container is needed). + +State lives entirely in **PostgreSQL** (Cloudron `postgresql` addon). Windmill +uses Postgres `LISTEN/NOTIFY` for job queuing, so **no Redis is required**. + +## Authentication + +Windmill supports **OIDC** and **SAML** natively. Unlike many apps, these are +configured in the **in-app Admin Settings UI** (persisted in the database), +not via environment variables. + +### Post-install OIDC setup (recommended) + +1. Open the Windmill app and sign in as the bootstrap superadmin (the first run + prints a `SUPERADMIN_SECRET` / creates an admin — see Windmill docs). +2. Go to **Admin Settings → Auth → OIDC**. +3. Enter your identity provider details (Cloudron's OIDC provider issuer, + client ID, and client secret). The platform OIDC issuer / client creds come + from your Cloudron instance's app SSO configuration. +4. Save; users can then log in via OIDC. + +> OIDC is the preferred auth path for this app. Until OIDC is configured, + access is limited to the local superadmin account. + +## Features + +- **Scripts to endpoints**: any script becomes a typed HTTP API + background job +- **Flows**: visually chain scripts with branching, loops, retries, error handling +- **Schedules**: cron-based job scheduling +- **Apps**: generate internal UIs from flows +- **Multi-language**: Python, JS/TS, Go, Bash, SQL, PHP, Rust, PowerShell, Deno +- **Secrets**: encrypted secret management with inheritance +- **Queuing**: Postgres `LISTEN/NOTIFY` (no external broker) + +## Configuration + +### Ports +- **8000**: Windmill web UI + REST API + +### Addons +- **postgresql** (v14): all persistent state, jobs, flows, users, queue +- **localstorage** (`/app/data`): ephemeral job working files + +### Environment Variables +The `start.sh` entrypoint derives `DATABASE_URL` automatically from the +Cloudron PostgreSQL addon. The only fixed knob is: + +| Variable | Default | Purpose | +|----------|---------|---------| +| `MODE` | `server` | Run mode (server embeds a default worker) | + +`DATABASE_URL` is composed at runtime as +`postgres://$USER:$PASS@$HOST:$PORT/$DB?sslmode=disable`. + +## Usage + +1. Install the package on Cloudron (provisions a PostgreSQL database). +2. On first boot, Windmill runs migrations and bootstraps a superadmin. +3. Sign in, then immediately configure OIDC under Admin Settings (above). +4. Create a script, expose it as a flow/app, schedule it, or call its HTTP endpoint. + +## Upstream + +- **Repository**: https://github.com/windmill-labs/windmill +- **Image**: `ghcr.io/windmill-labs/windmill:1.514.1` +- **Docs**: https://www.windmill.dev/docs diff --git a/Package-Workspace/Automation/windmill/logo.png b/Package-Workspace/Automation/windmill/logo.png new file mode 100644 index 0000000..0abb8df Binary files /dev/null and b/Package-Workspace/Automation/windmill/logo.png differ diff --git a/Package-Workspace/Automation/windmill/start.sh b/Package-Workspace/Automation/windmill/start.sh new file mode 100755 index 0000000..a896972 --- /dev/null +++ b/Package-Workspace/Automation/windmill/start.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -euo pipefail + +# Build the PostgreSQL connection URL from the Cloudron postgresql addon. +export DATABASE_URL="postgres://${CLOUDRON_POSTGRESQL_USERNAME}:${CLOUDRON_POSTGRESQL_PASSWORD}@${CLOUDRON_POSTGRESQL_HOST}:${CLOUDRON_POSTGRESQL_PORT}/${CLOUDRON_POSTGRESQL_DATABASE}?sslmode=disable" + +# Single-container server mode (server embeds a default worker). +export MODE="${MODE:-server}" + +# Wait for PostgreSQL to accept connections before starting. Windmill runs SQL +# migrations on startup, so the DB must be reachable. Uses bash /dev/tcp (no +# pg_isready dependency). +echo "Waiting for PostgreSQL at ${CLOUDRON_POSTGRESQL_HOST}:${CLOUDRON_POSTGRESQL_PORT} ..." +for i in $(seq 1 60); do + if (exec 3<>"/dev/tcp/${CLOUDRON_POSTGRESQL_HOST}/${CLOUDRON_POSTGRESQL_PORT}") 2>/dev/null; then + exec 3>&- 3<&- || true + echo "PostgreSQL is reachable." + break + fi + echo " not ready yet, retrying in 2s ($i/60)" + sleep 2 +done + +cd /usr/src/app +exec windmill diff --git a/README.md b/README.md index ffa6595..43cc97c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The Cloudron component focuses on packaging upstream free/libre/open application ### 📊 Current Progress - **Total Applications**: ~57 (see [GitUrlList.txt](GitUrlList.txt)) -- **Completed Packages**: 8/~57 (~14%) +- **Completed Packages**: 9/~57 (~16%) - **Packaging Templates**: Created ✅ - **Packages Committed & Pushed**: 7 ✅ @@ -27,6 +27,7 @@ The Cloudron component focuses on packaging upstream free/libre/open application | 6 | Puter | Development | 361MB | 4100 | localstorage, postgresql | ✅ Committed | | 7 | Corteza | Low-Code | 436MB | 80 | localstorage, postgresql | ✅ Committed | | 8 | draw.io | Documentation-Tools | — | 8080 | none (auth proxy) | ✅ Committed | +| 9 | Windmill | Automation | ~2GB | 8000 | localstorage, postgresql | ✅ Committed | ### 📦 Packages in Development @@ -60,7 +61,7 @@ None currently in development. ### ⚡ Productivity Metrics -- **Packages Completed**: 8/~57 (~14%) +- **Packages Completed**: 9/~57 (~16%) - **Average Package Time**: ~30 minutes - **Success Rate**: 100% (all packages built successfully) - **Commits Pushed**: 100% (all packages pushed to remote) @@ -75,7 +76,7 @@ Applications are organized by function rather than programming language: | Functional Category | Description | App Count | Packages Completed | |---|---|---|---| | **API-Gateway** | API management and gateway solutions | 2 | 2/2 (100%) ✅ | -| **Automation** | Workflow automation and scripting tools | 4 | 0/4 (0%) | +| **Automation** | Workflow automation and scripting tools | 4 | 1/4 (25%) | | **Business-Apps** | Enterprise business applications | 9 | 0/9 (0%) | | **Collaboration** | Team collaboration and communication | 2 | 0/2 (0%) | | **Communication** | Messaging and communication platforms | 2 | 0/2 (0%) | @@ -151,7 +152,7 @@ Applications are organized by function rather than programming language: | [SDRangel](https://github.com/f4exb/sdrangel) | [GitHub](https://github.com/f4exb/sdrangel) | Software defined radio application | Infrastructure | | [No-Code Architects Toolkit](https://github.com/stephengpope/no-code-architects-toolkit) | [GitHub](https://github.com/stephengpope/no-code-architects-toolkit) | No-code development toolkit | Low-Code | | [Warp](https://github.com/sebo-b/warp) | [GitHub](https://github.com/sebo-b/warp) | Terminal and shell enhancement tool | Development | | -| [Windmill](https://github.com/windmill-labs/windmill) | [GitHub](https://github.com/windmill-labs/windmill) | Open-source workflow automation platform | Automation | +| [Windmill](https://github.com/windmill-labs/windmill) | [GitHub](https://github.com/windmill-labs/windmill) | Open-source workflow automation platform | Automation | ✅ Packaged | | [Corteza](https://github.com/cortezaproject/corteza) | [GitHub](https://github.com/cortezaproject/corteza) | Open-source low-code platform | Low-Code | | [Security Awareness Training](https://github.com/security-companion/security-awareness-training) | [GitHub](https://github.com/security-companion/security-awareness-training) | Security awareness training platform | Security | | [Comply](https://github.com/strongdm/comply) | [GitHub](https://github.com/strongdm/comply) | Compliance and audit management | Security | diff --git a/STATUS.md b/STATUS.md index 815017b..b4eb30f 100644 --- a/STATUS.md +++ b/STATUS.md @@ -3,16 +3,16 @@ > **Human read-only. Agents maintain this file automatically after each work > session.** Do not edit by hand — the next agent run will overwrite it. > -> **Last updated:** 2026-07-30 by Crush (GLM-5.2) — draw.io packaged (auth-proxy -> pattern); mandatory auth policy established. +> **Last updated:** 2026-07-30 by Crush (GLM-5.2) — Windmill packaged (OIDC, +> PostgreSQL, no Redis); draw.io + Windmill validated end-to-end with docker. ## Current State: STABLE (packaging phase, ongoing) -Cloudron packaging pipeline is operational. 8 of ~57 upstream applications are +Cloudron packaging pipeline is operational. 9 of ~57 upstream applications are packaged, committed, and pushed. Packaging templates exist for the core patterns. The gardening protocol (this file + AGENTS.md) keeps docs in sync. -## Completed Packages (8) +## Completed Packages (9) | # | Application | Category | Pattern | Port(s) | Addons | |---|-------------|----------|---------|---------|--------| @@ -24,6 +24,7 @@ patterns. The gardening protocol (this file + AGENTS.md) keeps docs in sync. | 6 | Puter | Development | Multi-stage (Node.js) | 4100 | localstorage, postgresql | | 7 | Corteza | Low-Code | Pre-compiled binaries | 80 | localstorage, postgresql | | 8 | draw.io | Documentation-Tools | Official-image wrapper + auth proxy | 8080 | none (stateless) | +| 9 | Windmill | Automation | Official-image wrapper + start.sh | 8000 | localstorage, postgresql | Each package lives in `Package-Workspace///` and contains a `Dockerfile`, `CloudronManifest.json`, `README.md`, `CHANGELOG.md`, `logo.png`, @@ -49,7 +50,7 @@ Full write-ups of each pattern + challenges are in [`JOURNAL.md`](JOURNAL.md). | Documentation-Tools | 3 | 2/3 | wireviz-web, draw.io done | | Low-Code | 3 | 1/3 | corteza done | | Monitoring | 6 | 1/6 | healthchecks done | -| Automation | 4 | 0/4 | | +| Automation | 4 | 1/4 | windmill done | | Business-Apps | 8 | 0/8 | | | Collaboration | 2 | 0/2 | | | Communication | 1 | 0/1 | | @@ -71,7 +72,7 @@ Auth capability is a hard gate before packaging (see LDAP acceptable (risk flag), 🔄 = auth-proxy (no users), ❌ = local-only (unacceptable / blocked-on-auth). -### Completed packages (7) +### Completed packages (9) | App | OIDC | LDAP | Verdict | Note | |-----|------|------|---------|------| @@ -82,21 +83,22 @@ LDAP acceptable (risk flag), 🔄 = auth-proxy (no users), ❌ = local-only | WireViz Web | n/a | n/a | 🔄 proxy-eligible | Stateless, no users; **auth-gap: needs `httpAuth` proxy added** | | Puter | no | no | ❌ risk | Own user system, no SSO federation — needs revisit | | Corteza | yes | no | ✅ preferred | Native OIDC via `auth.external.providers.openid-connect.*` | +| draw.io | n/a | n/a | 🔄 proxy | **Packaged** with `httpAuth.type=proxy` (no users, stateless) | +| Windmill | yes | no | ✅ preferred | **Packaged**; OIDC configured via Admin Settings UI (no env vars) | ### Candidates researched | App | OIDC | LDAP | Verdict | Note | |-----|------|------|---------|------| -| docker-drawio | n/a | n/a | 🔄 proxy-eligible | Stateless diagramming; package with `httpAuth` proxy | -| Windmill | yes | no | ✅ preferred | OIDC native; configured via Admin Settings UI (no env vars) | | NetBox | yes | yes | ✅ auth, ❌ Redis | OIDC+LDAP native, but HARD Redis dep (Cloudron has none) — Complex | | Gophish | no | no | ❌ blocked | Local admin login only, no SSO — do not package until auth added | -**Immediate queue:** Windmill (OIDC). +**Immediate queue:** research next OIDC/auth-proxy candidates (Sentry, SigNoz, +Langfuse, Fleet, InvenTree, GoAlert) and pick the cleanest wins. **Deferred:** NetBox (bundle Valkey+supervisor — significant), Gophish (blocked-on-auth). **Tech debt:** add `httpAuth` proxy to Webhook + WireViz Web (stateless apps); -revise Puter auth. draw.io ✅ packaged with auth proxy. +revise Puter auth. ## Known Issues