diff --git a/Dockerfile b/Dockerfile
index 3e1095a..c4b94f4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,8 +1,8 @@
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
ARG DEBIAN_IMAGE=debian:bookworm-slim
-ARG RUST_IMAGE=rust:1.80-slim-bookworm
-ARG PYTHON_IMAGE=python:3.12-slim
+ARG RUST_IMAGE=rust:1.90-slim-bookworm
+ARG PYTHON_IMAGE=python:3.12-slim-bookworm
FROM ${RUST_IMAGE} AS rust_base
@@ -14,7 +14,7 @@ RUN apt-get -y update \
RUN rustup component add rustfmt
-RUN CARGO_NET_GIT_FETCH_WITH_CLI=true cargo install cargo-chef --version ^0.1
+RUN CARGO_NET_GIT_FETCH_WITH_CLI=true cargo install cargo-chef --version 0.1.68
RUN cargo install sccache --version ^0.8
ENV RUSTC_WRAPPER=sccache SCCACHE_DIR=/backend/sccache
@@ -23,11 +23,26 @@ WORKDIR /windmill
ENV SQLX_OFFLINE=true
# ENV CARGO_INCREMENTAL=1
-FROM node:20-alpine as frontend
+FROM rust_base AS windmill_duckdb_ffi_internal_builder
+
+WORKDIR /windmill-duckdb-ffi-internal
+
+RUN apt-get update && apt-get install -y clang=1:14.0-55.* libclang-dev=1:14.0-55.* cmake=3.25.* && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+COPY ./backend/windmill-duckdb-ffi-internal .
+
+RUN --mount=type=cache,target=/usr/local/cargo/registry \
+ --mount=type=cache,target=$SCCACHE_DIR,sharing=locked \
+ cargo build --release -p windmill_duckdb_ffi_internal
+
+FROM node:24-alpine AS frontend
# install dependencies
WORKDIR /frontend
COPY ./frontend/package.json ./frontend/package-lock.json ./
+COPY ./frontend/scripts/ ./scripts/
RUN npm ci
# Copy all local files into the image.
@@ -36,15 +51,17 @@ RUN mkdir /backend
COPY /backend/windmill-api/openapi.yaml /backend/windmill-api/openapi.yaml
COPY /openflow.openapi.yaml /openflow.openapi.yaml
COPY /backend/windmill-api/build_openapi.sh /backend/windmill-api/build_openapi.sh
+COPY /system_prompts/auto-generated /system_prompts/auto-generated
RUN cd /backend/windmill-api && . ./build_openapi.sh
COPY /backend/parsers/windmill-parser-wasm/pkg/ /backend/parsers/windmill-parser-wasm/pkg/
COPY /typescript-client/docs/ /frontend/static/tsdocs/
+COPY /python-client/docs/ /frontend/static/pydocs/
RUN npm run generate-backend-client
RUN sed -i "s|BASE: '/api'|BASE: '/index.php/apps/app_api/proxy/flow/api'|" /frontend/src/lib/gen/core/OpenAPI.ts
-ENV NODE_OPTIONS "--max-old-space-size=8192"
-ARG VITE_BASE_URL ""
+ENV NODE_OPTIONS="--max-old-space-size=8192"
+ARG VITE_BASE_URL=""
RUN npm run build
FROM scratch AS export_frontend
@@ -89,19 +106,29 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \
FROM ${PYTHON_IMAGE}
ARG TARGETPLATFORM
-ARG POWERSHELL_VERSION=7.3.5
-ARG POWERSHELL_DEB_VERSION=7.3.5-1
+ARG POWERSHELL_VERSION=7.5.0
+ARG POWERSHELL_DEB_VERSION=7.5.0-1
ARG KUBECTL_VERSION=1.28.7
ARG HELM_VERSION=3.14.3
-ARG GO_VERSION=1.22.5
+ARG GO_VERSION=1.25.0
ARG APP=/usr/src/app
ARG WITH_POWERSHELL=true
ARG WITH_KUBECTL=true
ARG WITH_HELM=true
ARG WITH_GIT=true
+ARG LATEST_STABLE_PY=3.12
+ENV UV_PYTHON_INSTALL_DIR=/tmp/windmill/cache/py_runtime
+ENV UV_PYTHON_PREFERENCE=only-managed
+
+RUN mkdir -p /usr/local/uv
+ENV UV_TOOL_BIN_DIR=/usr/local/bin
+ENV UV_TOOL_DIR=/usr/local/uv
+
+ENV PATH=/usr/local/bin:/root/.local/bin:/tmp/.local/bin:$PATH
+
RUN apt-get update \
- && apt-get install -y ca-certificates wget curl jq unzip build-essential unixodbc xmlsec1 software-properties-common \
+ && apt-get install -y --no-install-recommends netbase tzdata ca-certificates wget curl jq unzip build-essential unixodbc xmlsec1 tini \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
@@ -113,18 +140,23 @@ RUN if [ "$WITH_GIT" = "true" ]; then \
else echo 'Building the image without git'; fi;
RUN if [ "$WITH_POWERSHELL" = "true" ]; then \
- if [ "$TARGETPLATFORM" = "linux/amd64" ]; then apt-get update -y && apt install libicu-dev -y && wget -O 'pwsh.deb' "https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell_${POWERSHELL_DEB_VERSION}.deb_amd64.deb" && apt-get clean \
- && rm -rf /var/lib/apt/lists/* && \
- dpkg --install 'pwsh.deb' && \
- rm 'pwsh.deb'; \
- elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then apt-get update -y && apt install libicu-dev -y && wget -O powershell.tar.gz "https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-arm64.tar.gz" && apt-get clean \
- && rm -rf /var/lib/apt/lists/* && \
+ apt-get update -y && apt-get install -y libicu72 && \
+ if [ "$TARGETPLATFORM" = "linux/amd64" ]; then \
+ wget -O 'pwsh.tar.gz' "https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz" && \
+ mkdir -p /opt/microsoft/powershell/7 && \
+ tar zxf pwsh.tar.gz -C /opt/microsoft/powershell/7 && \
+ chmod +x /opt/microsoft/powershell/7/pwsh && \
+ ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \
+ rm pwsh.tar.gz; \
+ elif [ "$TARGETPLATFORM" = "linux/arm64" ]; then \
+ wget -O powershell.tar.gz "https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/powershell-${POWERSHELL_VERSION}-linux-arm64.tar.gz" && \
mkdir -p /opt/microsoft/powershell/7 && \
tar zxf powershell.tar.gz -C /opt/microsoft/powershell/7 && \
chmod +x /opt/microsoft/powershell/7/pwsh && \
ln -s /opt/microsoft/powershell/7/pwsh /usr/bin/pwsh && \
rm powershell.tar.gz; \
- else echo 'Could not install pwshell, not on amd64 or arm64'; fi; \
+ else echo 'Could not install pwshell, not on amd64 or arm64'; fi; \
+ apt-get clean && rm -rf /var/lib/apt/lists/*; \
else echo 'Building the image without powershell'; fi
RUN if [ "$WITH_HELM" = "true" ]; then \
@@ -161,23 +193,50 @@ RUN set -eux; \
ENV PATH="${PATH}:/usr/local/go/bin"
ENV GO_PATH=/usr/local/go/bin/go
+# Install UV
+RUN curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/uv/releases/download/0.6.2/uv-installer.sh | sh && mv /root/.local/bin/uv /usr/local/bin/uv
+
+# Preinstall python runtimes to temp build location (will copy with world-writable perms later)
+RUN UV_CACHE_DIR=/tmp/build_cache/uv UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install 3.11
+RUN UV_CACHE_DIR=/tmp/build_cache/uv UV_PYTHON_INSTALL_DIR=/tmp/build_cache/py_runtime uv python install $LATEST_STABLE_PY
+
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -
-RUN apt-get -y update && apt-get install -y curl nodejs awscli && apt-get clean \
+RUN apt-get -y update && apt-get install -y curl procps nodejs awscli && apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# go build is slower the first time it is ran, so we prewarm it in the build
-RUN mkdir -p /tmp/gobuildwarm && cd /tmp/gobuildwarm && go mod init gobuildwarm && printf "package foo\nimport (\"fmt\")\nfunc main() { fmt.Println(42) }" > warm.go && go mod tidy && go build -x && rm -rf /tmp/gobuildwarm
+RUN export GOCACHE=/tmp/build_cache/go && \
+ mkdir -p /tmp/gobuildwarm/inner && \
+ cd /tmp/gobuildwarm && \
+ go mod init mymod && \
+ printf 'package main\nimport (\n\t"encoding/json"\n\t"os"\n\t"fmt"\n\t"mymod/inner"\n)\nfunc main() {\n\tdat, _ := os.ReadFile("args.json")\n\tvar req inner.Req\n\tjson.Unmarshal(dat, &req)\n\tres, _ := inner.Run(req)\n\tres_json, _ := json.Marshal(res)\n\tfmt.Println(string(res_json))\n}' > main.go && \
+ printf 'package inner\ntype Req struct {\n\tX int `json:"x"`\n}\nfunc Run(req Req) (interface{}, error) {\n\treturn main(req.X)\n}\nfunc main(x int) (interface{}, error) {\n\treturn x, nil\n}' > inner/inner.go && \
+ go build -x . && \
+ rm -rf /tmp/gobuildwarm
+
+# Copy build caches to final location, then add write permissions for any UID
+# chmod a+rw adds read+write WITHOUT removing execute bits (755->777, 644->666)
+# Note: uv python install only creates py_runtime, not uv cache - we create uv/go dirs for runtime
+RUN mkdir -p /tmp/windmill/cache && \
+ cp -r /tmp/build_cache/* /tmp/windmill/cache/ && \
+ chmod -R a+rw /tmp/windmill/cache && \
+ rm -rf /tmp/build_cache && \
+ mkdir -p -m 777 /tmp/windmill/cache/uv /tmp/windmill/cache/go
+
+# Runtime cache locations
+ENV UV_CACHE_DIR=/tmp/windmill/cache/uv
+ENV UV_PYTHON_INSTALL_DIR=/tmp/windmill/cache/py_runtime
+ENV GOCACHE=/tmp/windmill/cache/go
ENV TZ=Etc/UTC
-RUN /usr/local/bin/python3 -m pip install pip-tools
-
COPY --from=builder /frontend/build /static_frontend
COPY --from=builder /windmill/target/release/windmill ${APP}/windmill
+COPY --from=windmill_duckdb_ffi_internal_builder /windmill-duckdb-ffi-internal/target/release/libwindmill_duckdb_ffi_internal.so ${APP}/libwindmill_duckdb_ffi_internal.so
-COPY --from=denoland/deno:1.46.3 --chmod=755 /usr/bin/deno /usr/bin/deno
+COPY --from=denoland/deno:2.2.1 --chmod=755 /usr/bin/deno /usr/bin/deno
-COPY --from=oven/bun:1.1.25 /usr/local/bin/bun /usr/bin/bun
+COPY --from=oven/bun:1.2.23 /usr/local/bin/bun /usr/bin/bun
COPY --from=php:8.3.7-cli /usr/local/bin/php /usr/bin/php
COPY --from=composer:2.7.6 /usr/bin/composer /usr/bin/composer
@@ -187,6 +246,7 @@ COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/
ENV RUSTUP_HOME="/usr/local/rustup"
ENV CARGO_HOME="/usr/local/cargo"
+ENV LD_LIBRARY_PATH="."
WORKDIR ${APP}
@@ -194,7 +254,7 @@ RUN ln -s ${APP}/windmill /usr/local/bin/windmill
COPY ./frontend/src/lib/hubPaths.json ${APP}/hubPaths.json
-RUN windmill cache ${APP}/hubPaths.json && rm ${APP}/hubPaths.json && chmod -R 777 /tmp/windmill
+RUN windmill cache ${APP}/hubPaths.json && rm ${APP}/hubPaths.json
EXPOSE 8000
@@ -203,6 +263,12 @@ RUN apt-get update && \
curl nodejs sudo wget procps nano && \
rm -rf /var/lib/apt/lists/*
+# /tmp/.cache may be created by earlier build steps with 755; chmod ensures any UID can write
+RUN mkdir -p -m 777 /tmp/windmill/logs /tmp/windmill/search /tmp/.cache && chmod 777 /tmp/.cache
+
+# Make directories world-accessible for any UID
+RUN find ${APP} /tmp/windmill -type d -exec chmod 777 {} +
+
# HaRP: download and install FRP client
RUN set -ex; \
ARCH=$(uname -m); \
diff --git a/Makefile b/Makefile
index b0910ec..c15d96e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT
+SHELL := /bin/bash
.DEFAULT_GOAL := help
APP_ID := flow
@@ -33,7 +34,7 @@ help:
.PHONY: init
init:
rm -rf windmill_src
- git -c advice.detachedHead=False clone -b v1.394.4 https://github.com/windmill-labs/windmill.git windmill_src
+ git -c advice.detachedHead=False clone -b v1.603.4 https://github.com/windmill-labs/windmill.git windmill_src
cp Dockerfile requirements.txt windmill_src/
cp -r ex_app windmill_src/
@@ -55,11 +56,22 @@ build-push:
docker login ghcr.io
docker buildx build --push \
--build-arg VITE_BASE_URL=/index.php/apps/app_api/proxy/flow \
+ --build-arg features=python \
--platform linux/arm64/v8,linux/amd64 \
--tag ghcr.io/nextcloud/$(APP_ID):$(APP_VERSION) \
--file windmill_src/Dockerfile \
windmill_src
+.PHONY: build-amd64
+build-amd64:
+ docker buildx build --load \
+ --build-arg VITE_BASE_URL=/index.php/apps/app_api/proxy/flow \
+ --build-arg features=python \
+ --platform linux/amd64 \
+ --tag ghcr.io/nextcloud/$(APP_ID):$(APP_VERSION) \
+ --file windmill_src/Dockerfile \
+ windmill_src
+
.PHONY: run30
run30:
docker exec master-stable30-1 sudo -u www-data php occ app_api:app:unregister $(APP_ID) --silent --force || true
diff --git a/README.md b/README.md
index 0eca133..4ff6b20 100644
--- a/README.md
+++ b/README.md
@@ -105,10 +105,10 @@ Follow these steps to manually deploy Flow without Docker:
**Note:** If you are using a non-standard version of Windmill from the ExApp, please adjust its version in the `Makefile` by editing the line under the `init` target:
```makefile
- git -c advice.detachedHead=False clone -b v1.394.4 https://github.com/windmill-labs/windmill.git windmill_src
+ git -c advice.detachedHead=False clone -b v1.603.4 https://github.com/windmill-labs/windmill.git windmill_src
```
- Replace `v1.394.4` with your desired Windmill version.
+ Replace `v1.603.4` with your desired Windmill version.
7. **Initialize Windmill Source and Build Frontend**
@@ -148,10 +148,10 @@ Follow these steps to manually deploy Flow without Docker:
*Windmill will be deployed as per its official documentation. The following steps simplify its integration with Nextcloud's development setup.*
-1. In the `.env` file used for deploying Windmill's Docker Compose containers, set the desired Windmill version. The current version can be found in the `Makefile` (e.g., `1.394.4`). Adjust the following line accordingly:
+1. In the `.env` file used for deploying Windmill's Docker Compose containers, set the desired Windmill version. The current version can be found in the `Makefile` (e.g., `1.603.4`). Adjust the following line accordingly:
```bash
- WM_IMAGE=ghcr.io/windmill-labs/windmill:1.394.4
+ WM_IMAGE=ghcr.io/windmill-labs/windmill:1.603.4
```
2. Add the `master_default` network (or the network name used for Nextcloud in your Julius `nextcloud-docker-dev` setup) to each container in Windmill's `docker-compose.yml`.
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 11ad284..0092555 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -24,7 +24,7 @@ This app provides an easy way to install the Windmill based Business Process Aut
**Requires [`AppAPI`](https://github.com/nextcloud/app_api) and `webhook_listeners` to be enabled to work.**
]]>
- 1.2.2
+ 1.3.0
agpl
Julien Veyssier
Marcel Klehr
@@ -45,7 +45,7 @@ This app provides an easy way to install the Windmill based Business Process Aut
ghcr.io
nextcloud/flow
- 1.2.0
+ 1.3.0
diff --git a/ex_app_scripts/common_pgsql.sh b/ex_app_scripts/common_pgsql.sh
index 8bf76d0..73f3ffb 100644
--- a/ex_app_scripts/common_pgsql.sh
+++ b/ex_app_scripts/common_pgsql.sh
@@ -17,9 +17,16 @@ ensure_postgres_installed() {
else
echo "PostgreSQL binaries not found."
echo "Adding the PostgreSQL APT repository..."
- apt-get update && apt-get install -y gnupg
- wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
- echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
+ apt-get update && apt-get install -y gnupg curl
+ # Use modern method for GPG keys (apt-key is deprecated)
+ mkdir -p /etc/apt/keyrings
+ curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/keyrings/postgresql.gpg
+ # Use bookworm as fallback for newer Debian versions (trixie/sid)
+ DISTRO=$(lsb_release -cs 2>/dev/null || echo "bookworm")
+ if [ "$DISTRO" = "trixie" ] || [ "$DISTRO" = "sid" ]; then
+ DISTRO="bookworm"
+ fi
+ echo "deb [signed-by=/etc/apt/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ ${DISTRO}-pgdg main" > /etc/apt/sources.list.d/pgdg.list
echo "Installing PostgreSQL..."
apt-get update && apt-get install -y postgresql-$PG_VERSION
fi