From 5cbdb00ff49a2379fe0687edea3aefb8753c5688 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 02:10:58 +0000 Subject: [PATCH] WIP: windmill derived image builds successfully, adding rootless + read-only Agent-Logs-Url: https://github.com/nextcloud/all-in-one/sessions/6f198732-63c3-41b7-8b2e-1b5fa565ee21 Co-authored-by: szaimen <42591237+szaimen@users.noreply.github.com> --- Containers/windmill/Dockerfile | 77 +++++++++++++++++++++++++++ Containers/windmill/healthcheck.sh | 6 +++ Containers/windmill/start.sh | 49 +++++++++++++++++ Containers/windmill/supervisord.conf | 30 +++++++++++ Containers/windmill/windmill-start.sh | 10 ++++ php/containers.json | 39 ++++++++------ 6 files changed, 195 insertions(+), 16 deletions(-) create mode 100644 Containers/windmill/Dockerfile create mode 100644 Containers/windmill/healthcheck.sh create mode 100644 Containers/windmill/start.sh create mode 100644 Containers/windmill/supervisord.conf create mode 100644 Containers/windmill/windmill-start.sh diff --git a/Containers/windmill/Dockerfile b/Containers/windmill/Dockerfile new file mode 100644 index 00000000..82d8e0d8 --- /dev/null +++ b/Containers/windmill/Dockerfile @@ -0,0 +1,77 @@ +# syntax=docker/dockerfile:latest +# Stage 1: PostgreSQL server from the official Debian bookworm image +# (matches the Debian bookworm base used by windmill-labs/windmill) +FROM postgres:17-bookworm AS postgres-base + +# Final stage: derive from the official Windmill image and bundle PostgreSQL +FROM ghcr.io/windmill-labs/windmill:main + +USER root + +ARG DEBIAN_FRONTEND=noninteractive + +# Copy PostgreSQL server binaries, libraries, and utilities from the postgres stage +COPY --from=postgres-base /usr/lib/postgresql /usr/lib/postgresql +COPY --from=postgres-base /usr/share/postgresql /usr/share/postgresql +COPY --from=postgres-base /usr/bin/pg_dump \ + /usr/bin/pg_dumpall \ + /usr/bin/pg_restore \ + /usr/bin/ + +# Install supervisor from standard Debian repos (remove broken external sources first) +# hadolint ignore=DL3008 +RUN set -ex; \ + rm -f \ + /etc/apt/sources.list.d/nodesource.sources \ + /etc/apt/sources.list.d/pgdg.list; \ + apt-get update; \ + apt-get upgrade -y; \ + apt-get install -y --no-install-recommends \ + supervisor \ + tzdata \ + netcat-openbsd; \ + rm -rf /var/lib/apt/lists/*; \ + \ + # Create the postgres system user and group (without a fixed GID to avoid conflicts) + groupadd -r postgres || true; \ + useradd -r -g postgres --home-dir=/var/lib/postgresql --shell=/bin/bash postgres || true; \ + \ + # Create required directories + mkdir -p \ + /var/lib/postgresql/data \ + /var/run/postgresql \ + /var/log/supervisord \ + /var/run/supervisord \ + /tmp/windmill/cache; \ + chown -R postgres:postgres /var/lib/postgresql /var/run/postgresql; \ + chmod 775 /var/run/postgresql; \ + chmod 777 \ + /var/log/supervisord \ + /var/run/supervisord \ + /tmp/windmill/cache; \ + \ + # Create a symlink so 'postgres' and other pg tools are on PATH + ln -sf /usr/lib/postgresql/17/bin/postgres /usr/local/bin/postgres; \ + ln -sf /usr/lib/postgresql/17/bin/initdb /usr/local/bin/initdb; \ + ln -sf /usr/lib/postgresql/17/bin/pg_ctl /usr/local/bin/pg_ctl + +COPY --chmod=775 start.sh /start.sh +COPY --chmod=775 healthcheck.sh /healthcheck.sh +COPY --chmod=775 windmill-start.sh /windmill-start.sh +COPY --chmod=664 supervisord.conf /supervisord.conf + +VOLUME ["/var/lib/postgresql/data", "/tmp/windmill/cache"] + +EXPOSE 8000 + +ENTRYPOINT ["/start.sh"] + +HEALTHCHECK CMD /healthcheck.sh +LABEL com.centurylinklabs.watchtower.enable="false" \ + wud.watch="false" \ + org.opencontainers.image.title="Windmill for Nextcloud AIO" \ + org.opencontainers.image.description="Windmill workflow engine with bundled PostgreSQL for Nextcloud All-in-One" \ + org.opencontainers.image.url="https://github.com/nextcloud/all-in-one" \ + org.opencontainers.image.source="https://github.com/nextcloud/all-in-one" \ + org.opencontainers.image.vendor="Nextcloud" \ + org.opencontainers.image.documentation="https://github.com/nextcloud/all-in-one/blob/main/readme.md" diff --git a/Containers/windmill/healthcheck.sh b/Containers/windmill/healthcheck.sh new file mode 100644 index 00000000..41f50d66 --- /dev/null +++ b/Containers/windmill/healthcheck.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Check if Windmill is accepting connections on port 8000 +if ! nc -z localhost 8000; then + exit 1 +fi diff --git a/Containers/windmill/start.sh b/Containers/windmill/start.sh new file mode 100644 index 00000000..6ee0329a --- /dev/null +++ b/Containers/windmill/start.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +# Validate required environment variables +if [ -z "$BASE_URL" ]; then + echo "BASE_URL must be provided. Exiting!" + exit 1 +fi + +export TZ="${TZ:-Etc/UTC}" +PGDATA="/var/lib/postgresql/data" + +# Fix runtime directory permissions (tmpfs mounts start owned by root) +chown postgres:postgres /var/run/postgresql +chmod 775 /var/run/postgresql + +# Initialize PostgreSQL data directory on first run +if [ -z "$(ls -A "$PGDATA" 2>/dev/null)" ]; then + echo "Initializing PostgreSQL database for Windmill..." + + # Ensure the data directory is owned by postgres before initdb + chown postgres:postgres "$PGDATA" + + # Run initdb as the postgres user + su postgres -s /bin/bash -c "initdb -D '$PGDATA' --username=postgres --auth-local=trust --auth-host=trust --no-instructions" + + # Allow connections from localhost without a password + cat > "$PGDATA/pg_hba.conf" << 'EOF' +# TYPE DATABASE USER ADDRESS METHOD +local all all trust +host all all 127.0.0.1/32 trust +host all all ::1/128 trust +EOF + + # Only listen on localhost; the database is not exposed externally + cat >> "$PGDATA/postgresql.conf" << 'EOF' +listen_addresses = 'localhost' +EOF + + # Start PostgreSQL temporarily to create the windmill database and user + su postgres -s /bin/bash -c "pg_ctl -D '$PGDATA' start -w -o '-k /var/run/postgresql'" + su postgres -s /bin/bash -c "psql -h /var/run/postgresql -c \"CREATE USER windmill;\"" + su postgres -s /bin/bash -c "psql -h /var/run/postgresql -c \"CREATE DATABASE windmill OWNER windmill;\"" + su postgres -s /bin/bash -c "pg_ctl -D '$PGDATA' stop" + + echo "PostgreSQL initialization complete." +fi + +exec supervisord -c /supervisord.conf diff --git a/Containers/windmill/supervisord.conf b/Containers/windmill/supervisord.conf new file mode 100644 index 00000000..15c99492 --- /dev/null +++ b/Containers/windmill/supervisord.conf @@ -0,0 +1,30 @@ +[supervisord] +nodaemon=true +logfile=/var/log/supervisord/supervisord.log +pidfile=/var/run/supervisord/supervisord.pid +childlogdir=/var/log/supervisord/ +logfile_maxbytes=50MB +logfile_backups=10 +loglevel=error + +[program:postgresql] +user=postgres +command=postgres -D /var/lib/postgresql/data -k /var/run/postgresql +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +# Start first: Windmill depends on PostgreSQL being ready +priority=10 +autorestart=true +startsecs=5 + +[program:windmill] +command=/windmill-start.sh +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +priority=20 +autorestart=true +startsecs=10 diff --git a/Containers/windmill/windmill-start.sh b/Containers/windmill/windmill-start.sh new file mode 100644 index 00000000..8d2d0040 --- /dev/null +++ b/Containers/windmill/windmill-start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Wait for PostgreSQL to accept connections +until pg_isready -h localhost -q 2>/dev/null; do + echo "Waiting for PostgreSQL to be ready..." + sleep 2 +done + +# Start Windmill +exec windmill diff --git a/php/containers.json b/php/containers.json index 7e751754..d8a60d66 100644 --- a/php/containers.json +++ b/php/containers.json @@ -110,8 +110,7 @@ ], "internal_port": "5432", "secrets": [ - "DATABASE_PASSWORD", - "WINDMILL_DB_PASSWORD" + "DATABASE_PASSWORD" ], "volumes": [ { @@ -130,9 +129,7 @@ "POSTGRES_DB=nextcloud_database", "POSTGRES_USER=nextcloud", "TZ=%TIMEZONE%", - "PGTZ=%TIMEZONE%", - "WINDMILL_DB_PASSWORD=%WINDMILL_DB_PASSWORD%", - "WINDMILL_ENABLED=%WINDMILL_ENABLED%" + "PGTZ=%TIMEZONE%" ], "stop_grace_period": 1800, "restart": "unless-stopped", @@ -966,35 +963,45 @@ }, { "container_name": "nextcloud-aio-windmill", - "image_tag": "main", + "image_tag": "%AIO_CHANNEL%", "display_name": "Windmill", - "image": "ghcr.io/windmill-labs/windmill", + "image": "ghcr.io/nextcloud-releases/aio-windmill", "init": true, - "depends_on": [ - "nextcloud-aio-database" - ], "internal_port": "8000", "expose": [ "8000" ], - "secrets": [ - "WINDMILL_DB_PASSWORD" - ], + "healthcheck": { + "start_period": "0s", + "test": "/healthcheck.sh", + "interval": "30s", + "timeout": "30s", + "start_interval": "5s", + "retries": 3 + }, "environment": [ - "DATABASE_URL=postgresql://windmill:%WINDMILL_DB_PASSWORD%@nextcloud-aio-database/windmill", - "WM_BASE_URL=https://%NC_DOMAIN%:3100", + "BASE_URL=https://%NC_DOMAIN%:3100", "TZ=%TIMEZONE%", "NUM_WORKERS=1", "MODE=standalone", - "DISABLE_NSJAIL=true" + "DISABLE_NSJAIL=true", + "DATABASE_URL=postgresql://windmill@localhost/windmill?host=/var/run/postgresql" ], "volumes": [ + { + "source": "nextcloud_aio_windmill_db", + "destination": "/var/lib/postgresql/data", + "writeable": true + }, { "source": "nextcloud_aio_windmill", "destination": "/tmp/windmill/cache", "writeable": true } ], + "backup_volumes": [ + "nextcloud_aio_windmill_db" + ], "restart": "unless-stopped", "profiles": [ "windmill"