From 149da9b763e4f5dd93d2905be89b5df81bb61934 Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Wed, 4 Feb 2026 18:48:16 +0000 Subject: [PATCH] feat: make nsjail available in all standard images (CE) (#7793) * feat: make nsjail available in all standard images (CE) Include nsjail binary and runtime deps in the main Dockerfile and DockerfileSlim so sandboxing is available out of the box. Flip DISABLE_NSJAIL default to false so nsjail is enabled by default. Remove DockerfileNsjail (now redundant) and the build_ee_nsjail CI job, pointing publish_ecr_s3 at the base EE image instead. Add iptables to DockerfileFullEe to preserve the functionality from the removed nsjail image. Co-Authored-By: Claude Opus 4.5 * revert: keep DISABLE_NSJAIL default as true Co-Authored-By: Claude Opus 4.5 * fix: pin publish_ecr_s3 to exact commit hash Add type=sha tag to build_ee so it pushes a commit-pinned image tag. Restore git hash lookup in publish_ecr_s3 to reference the exact image for that commit, avoiding race conditions with the mutable dev tag. Co-Authored-By: Claude Opus 4.5 * fix: publish_ecr_s3 depends on build_ee_full, uses release tag Only publish to S3 on tag releases, extracting static frontend from the ee-full image using the semver tag. Co-Authored-By: Claude Opus 4.5 * fix: remove stale windmill-ee-nsjail references, add nsjail to EE slim The windmill-ee-nsjail image is no longer published since DockerfileNsjail was deleted. Update all references to use the base EE image (which now includes nsjail), remove redundant nsjail deps from DockerfileExtra, and add nsjail build to DockerfileSlimEe for consistency with CE slim. Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- .github/workflows/docker-image.yml | 81 +++----------------------- Dockerfile | 25 ++++++++ backend/windmill-worker/src/worker.rs | 6 +- debugger/Dockerfile | 4 +- docker/DockerfileExtra | 13 +---- docker/DockerfileFullEe | 3 + docker/DockerfileNsjail | 82 --------------------------- docker/DockerfileSlim | 25 ++++++++ docker/DockerfileSlimEe | 25 ++++++++ docker/dev.nu | 7 --- frontend/README_DEV.md | 4 +- 11 files changed, 94 insertions(+), 181 deletions(-) delete mode 100644 docker/DockerfileNsjail diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 23e1a69c64..71948bac1f 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -24,11 +24,6 @@ on: description: "Tag the image" required: true default: "test" - nsjail: - description: "Build nsjail image (true, false)" - required: false - default: false - type: boolean slim: description: "Build slim image (true, false)" required: false @@ -106,7 +101,7 @@ jobs: build_ee: runs-on: ubicloud - if: (github.event_name != 'workflow_dispatch') || (github.event.inputs.ee || github.event.inputs.nsjail) + if: (github.event_name != 'workflow_dispatch') || github.event.inputs.ee steps: - uses: actions/checkout@v4 with: @@ -370,67 +365,10 @@ jobs: # ignore-unchanged: true # only-fixed: true - build_ee_nsjail: - needs: [build_ee] - runs-on: ubicloud - if: (github.event_name != 'pull_request') && ((github.event_name != 'workflow_dispatch') || (github.event.inputs.ee || github.event.inputs.nsjail)) - - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - ref: ${{ github.ref }} - - # - name: Set up Docker Buildx - # uses: docker/setup-buildx-action@v2 - - - uses: depot/setup-action@v1 - - - name: Docker meta - id: meta-ee-public - uses: docker/metadata-action@v5 - with: - images: | - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee-nsjail - flavor: | - latest=false - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,enable=true,priority=100,prefix=,suffix=,format=short - type=ref,event=branch - type=ref,event=pr - - - name: Login to registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Update Dockerfile image reference - run: | - sed -i 's|FROM ghcr.io/windmill-labs/windmill-ee:dev|FROM ghcr.io/${{ env.IMAGE_NAME }}-ee:${{ env.DEV_SHA }}|' ./docker/DockerfileNsjail - cat ./docker/DockerfileNsjail | grep "FROM" - - - name: Build and push publicly ee - uses: depot/build-push-action@v1 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - file: "./docker/DockerfileNsjail" - tags: | - ${{ steps.meta-ee-public.outputs.tags }} - labels: | - ${{ steps.meta-ee-public.outputs.labels }} - org.opencontainers.image.licenses=Windmill-Enterprise-License - publish_ecr_s3: - needs: [build_ee_nsjail] + needs: [build_ee_full] runs-on: ubicloud-standard-2-arm - if: (github.event_name != 'pull_request') && (github.event_name != - 'workflow_dispatch') + if: ${{ startsWith(github.ref, 'refs/tags/v') }} env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -449,23 +387,18 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: get git hash - if: github.event_name != 'pull_request' - id: git_hash - run: | - git_hash=$(git rev-parse --short "$GITHUB_SHA") - echo "GIT_HASH=${git_hash:0:7}" >> "$GITHUB_OUTPUT" + - name: Get version from tag + id: version + run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" - uses: shrink/actions-docker-extract@v3 - if: github.event_name != 'pull_request' id: extract with: image: |- - ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee-nsjail:${{ steps.git_hash.outputs.GIT_HASH }} + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-ee-full:${{ steps.version.outputs.VERSION }} path: "/static_frontend/." - uses: reggionick/s3-deploy@v4 - if: github.event_name != 'pull_request' with: folder: ${{ steps.extract.outputs.destination }} bucket: windmill-frontend diff --git a/Dockerfile b/Dockerfile index 8b15e5e79e..572e84e265 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,26 @@ ARG DEBIAN_IMAGE=debian:bookworm-slim ARG RUST_IMAGE=rust:1.90-slim-bookworm +FROM debian:bookworm-slim AS nsjail + +WORKDIR /nsjail + +RUN apt-get -y update \ + && apt-get install -y \ + bison=2:3.8.* \ + flex=2.6.* \ + g++=4:12.2.* \ + gcc=4:12.2.* \ + git=1:2.39.* \ + libprotobuf-dev=3.21.* \ + libnl-route-3-dev=3.7.* \ + make=4.3-4.1 \ + pkg-config=1.8.* \ + protobuf-compiler=3.21.* + +RUN git clone -b master --single-branch https://github.com/google/nsjail.git . && git checkout dccf911fd2659e7b08ce9507c25b2b38ec2c5800 +RUN make + FROM ${RUST_IMAGE} AS rust_base RUN apt-get update && apt-get install -y git libssl-dev pkg-config npm @@ -246,6 +266,11 @@ ENV RUSTUP_HOME="/usr/local/rustup" ENV CARGO_HOME="/usr/local/cargo" ENV LD_LIBRARY_PATH="." +# nsjail runtime deps and binary +RUN apt-get update && apt-get install -y libprotobuf-dev libnl-route-3-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* +COPY --from=nsjail /nsjail/nsjail /bin/nsjail + WORKDIR ${APP} RUN ln -s ${APP}/windmill /usr/local/bin/windmill diff --git a/backend/windmill-worker/src/worker.rs b/backend/windmill-worker/src/worker.rs index 1bc84df1cb..c8eab55741 100644 --- a/backend/windmill-worker/src/worker.rs +++ b/backend/windmill-worker/src/worker.rs @@ -486,7 +486,8 @@ lazy_static::lazy_static! { let stderr = String::from_utf8_lossy(&output.stderr); tracing::warn!( "nsjail test failed: {}. Jobs will run without nsjail sandboxing. \ - To enable nsjail: install nsjail binary or use windmill image with -nsjail suffix", + nsjail should be included in all standard windmill images. \ + Check that the nsjail binary is installed and working correctly.", stderr.trim() ); None @@ -495,7 +496,8 @@ lazy_static::lazy_static! { if e.kind() == std::io::ErrorKind::NotFound { tracing::warn!( "nsjail not found at '{}'. Jobs will run without nsjail sandboxing. \ - To enable nsjail: install nsjail binary or use windmill image with -nsjail suffix", + nsjail should be included in all standard windmill images. \ + Check that the nsjail binary is installed at the expected path.", nsjail_path ); } else { diff --git a/debugger/Dockerfile b/debugger/Dockerfile index 04b118a0de..fe2b769e7c 100644 --- a/debugger/Dockerfile +++ b/debugger/Dockerfile @@ -15,8 +15,8 @@ # With nsjail enabled: # docker run -p 5679:5679 --privileged windmill-debugger --nsjail -# Stage 1: Get nsjail and windmill from the official windmill image -FROM ghcr.io/windmill-labs/windmill-ee-nsjail:main AS windmill-source +# Stage 1: Get nsjail and windmill from the official windmill EE image +FROM ghcr.io/windmill-labs/windmill-ee:main AS windmill-source # Stage 2: Build the debug service FROM oven/bun:1 AS runtime diff --git a/docker/DockerfileExtra b/docker/DockerfileExtra index 87da8f9c81..79a1645217 100644 --- a/docker/DockerfileExtra +++ b/docker/DockerfileExtra @@ -17,12 +17,7 @@ # docker run -p 3001:3001 -p 3002:3002 -p 3003:3003 windmill-extra # ============================================================================ -# Stage 1: Get nsjail from the nsjail image -# ============================================================================ -FROM ghcr.io/windmill-labs/windmill-ee-nsjail:main AS nsjail-source - -# ============================================================================ -# Stage 2: Build final extra services image from windmill-slim +# Build final extra services image from windmill-ee-slim (includes nsjail) # ============================================================================ FROM ghcr.io/windmill-labs/windmill-ee-slim:latest AS final @@ -40,11 +35,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Install additional system dependencies # - shellcheck: for bash LSP -# - libprotobuf-dev, libnl-route-3-dev: for nsjail runtime RUN apt-get update && apt-get install -y --no-install-recommends \ shellcheck \ - libprotobuf-dev \ - libnl-route-3-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* @@ -68,9 +60,6 @@ RUN /usr/local/go/bin/go install -v golang.org/x/tools/gopls@latest # Copy Deno for Deno LSP COPY --from=denoland/deno:2.2.1 --chmod=755 /usr/bin/deno /usr/bin/deno -# Copy nsjail from nsjail image (for sandboxed debugging) -COPY --from=nsjail-source /bin/nsjail /bin/nsjail - # ============================================================================ # LSP Setup # ============================================================================ diff --git a/docker/DockerfileFullEe b/docker/DockerfileFullEe index 92745c6b18..85ca429ea6 100644 --- a/docker/DockerfileFullEe +++ b/docker/DockerfileFullEe @@ -51,6 +51,9 @@ RUN /usr/bin/java -jar /usr/bin/coursier about # Ruby RUN apt-get install -y ruby ruby-bundler +# iptables +RUN apt-get install -y iptables + # Fix UV cache permissions for non-root user support (uid 1000, etc.) # The uv tool install ansible command populates the UV cache with root-owned files RUN chmod -R a+rw /tmp/windmill/cache/uv && \ diff --git a/docker/DockerfileNsjail b/docker/DockerfileNsjail deleted file mode 100644 index 26116499c9..0000000000 --- a/docker/DockerfileNsjail +++ /dev/null @@ -1,82 +0,0 @@ -FROM debian:bookworm-slim AS nsjail - -WORKDIR /nsjail - -RUN apt-get -y update \ - && apt-get install -y \ - bison=2:3.8.* \ - flex=2.6.* \ - g++=4:12.2.* \ - gcc=4:12.2.* \ - git=1:2.39.* \ - libprotobuf-dev=3.21.* \ - libnl-route-3-dev=3.7.* \ - make=4.3-4.1 \ - pkg-config=1.8.* \ - protobuf-compiler=3.21.* - - -RUN git clone -b master --single-branch https://github.com/google/nsjail.git . && git checkout dccf911fd2659e7b08ce9507c25b2b38ec2c5800 -RUN make - -FROM alpine:3.14 AS oracledb-client - -ARG TARGETPLATFORM - -# Oracle DB Client for amd64 -COPY --from=ghcr.io/oracle/oraclelinux9-instantclient:23 /usr/lib/oracle/23/client64/lib /opt/oracle/23/amd64/lib - -# Oracle DB Client for arm64 -RUN mkdir -p /opt/oracle/23/arm64 \ - && cd /opt/oracle/23/arm64 \ - && wget https://download.oracle.com/otn_software/linux/instantclient/instantclient-basiclite-linux-arm64.zip \ - && unzip instantclient-basiclite-linux-arm64.zip && rm instantclient-basiclite-linux-arm64.zip && mv instantclient* ./lib - -RUN if [ "$TARGETPLATFORM" = "linux/arm64" ]; then \ - mv /opt/oracle/23/arm64/lib /opt/oracle/23/lib; \ - else \ - mv /opt/oracle/23/amd64/lib /opt/oracle/23/lib; \ - fi - -FROM ghcr.io/windmill-labs/windmill-ee:dev - -RUN apt-get update && apt-get install -y libprotobuf-dev libnl-route-3-dev - -# Rust -COPY --from=rust:1.80.1 /usr/local/cargo /usr/local/cargo -COPY --from=rust:1.80.1 /usr/local/rustup /usr/local/rustup -RUN /usr/local/cargo/bin/cargo install cargo-sweep --version ^0.7 - -# Ansible -RUN uv tool install ansible && [ -d "$(uv tool dir)/ansible/bin/" ] && find "$(uv tool dir)/ansible/bin/" -mindepth 1 -maxdepth 1 -type f -executable -regextype posix-extended -regex '^((.+/)?)[^.]+' -print0 | xargs -0 ln -s -t "$UV_TOOL_BIN_DIR/" || true - -# dotnet SDK -RUN wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh \ - && chmod +x dotnet-install.sh \ - && ./dotnet-install.sh --channel 9.0 --install-dir /usr/share/dotnet \ - && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet \ - && rm dotnet-install.sh - -# Oracle DB Client -COPY --from=oracledb-client /opt/oracle/23/lib /opt/oracle/23/lib -RUN apt-get -y update && apt-get install -y libaio1 -RUN echo /opt/oracle/23/lib > /etc/ld.so.conf.d/oracle-instantclient.conf && ldconfig - -# Nushell -COPY --from=ghcr.io/nushell/nushell:0.101.0-bookworm /usr/bin/nu /usr/bin/nu - -# Java -RUN apt-get install -y default-jdk -RUN curl -fLo coursier https://github.com/coursier/coursier/releases/download/v2.1.24/coursier \ - && mv ./coursier /usr/bin/coursier \ - && chmod +x /usr/bin/coursier -RUN /usr/bin/java -jar /usr/bin/coursier about - -# Ruby -RUN apt-get install -y ruby ruby-bundler - -# iptables -RUN apt-get install -y iptables - -COPY --from=nsjail /nsjail/nsjail /bin/nsjail - diff --git a/docker/DockerfileSlim b/docker/DockerfileSlim index 84420b8be2..155746cd64 100644 --- a/docker/DockerfileSlim +++ b/docker/DockerfileSlim @@ -1,5 +1,25 @@ ARG DEBIAN_IMAGE=debian:bookworm-slim +FROM debian:bookworm-slim AS nsjail + +WORKDIR /nsjail + +RUN apt-get -y update \ + && apt-get install -y \ + bison=2:3.8.* \ + flex=2.6.* \ + g++=4:12.2.* \ + gcc=4:12.2.* \ + git=1:2.39.* \ + libprotobuf-dev=3.21.* \ + libnl-route-3-dev=3.7.* \ + make=4.3-4.1 \ + pkg-config=1.8.* \ + protobuf-compiler=3.21.* + +RUN git clone -b master --single-branch https://github.com/google/nsjail.git . && git checkout dccf911fd2659e7b08ce9507c25b2b38ec2c5800 +RUN make + FROM ${DEBIAN_IMAGE} ARG APP=/usr/src/app @@ -39,6 +59,11 @@ COPY --from=oven/bun:1.3.8 /usr/local/bin/bun /usr/bin/bun # add the docker client to call docker from a worker if enabled COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/ +# nsjail runtime deps and binary +RUN apt-get update && apt-get install -y libprotobuf-dev libnl-route-3-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* +COPY --from=nsjail /nsjail/nsjail /bin/nsjail + WORKDIR ${APP} COPY --from=ghcr.io/windmill-labs/windmill:dev --chmod=755 ${APP}/windmill ${APP}/windmill diff --git a/docker/DockerfileSlimEe b/docker/DockerfileSlimEe index 80de5fd0c9..53fc9ae51d 100644 --- a/docker/DockerfileSlimEe +++ b/docker/DockerfileSlimEe @@ -1,5 +1,25 @@ ARG DEBIAN_IMAGE=debian:bookworm-slim +FROM debian:bookworm-slim AS nsjail + +WORKDIR /nsjail + +RUN apt-get -y update \ + && apt-get install -y \ + bison=2:3.8.* \ + flex=2.6.* \ + g++=4:12.2.* \ + gcc=4:12.2.* \ + git=1:2.39.* \ + libprotobuf-dev=3.21.* \ + libnl-route-3-dev=3.7.* \ + make=4.3-4.1 \ + pkg-config=1.8.* \ + protobuf-compiler=3.21.* + +RUN git clone -b master --single-branch https://github.com/google/nsjail.git . && git checkout dccf911fd2659e7b08ce9507c25b2b38ec2c5800 +RUN make + FROM ${DEBIAN_IMAGE} ARG APP=/usr/src/app @@ -39,6 +59,11 @@ COPY --from=oven/bun:1.3.8 /usr/local/bin/bun /usr/bin/bun # add the docker client to call docker from a worker if enabled COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/ +# nsjail runtime deps and binary +RUN apt-get update && apt-get install -y libprotobuf-dev libnl-route-3-dev \ + && apt-get clean && rm -rf /var/lib/apt/lists/* +COPY --from=nsjail /nsjail/nsjail /bin/nsjail + WORKDIR ${APP} COPY --from=ghcr.io/windmill-labs/windmill-ee:dev --chmod=755 ${APP}/windmill ${APP}/windmill diff --git a/docker/dev.nu b/docker/dev.nu index 77d2641204..ac976a42f7 100755 --- a/docker/dev.nu +++ b/docker/dev.nu @@ -75,13 +75,6 @@ def patch_docker_compose [ $compose.services.windmill_server.pull_policy = "never" $compose.services.windmill_indexer.pull_policy = "never" - if ($custom_dockerfile | default 'none' | path basename) == "DockerfileNsjail" { - $compose.services.windmill_worker.privileged = true - $compose.services.windmill_worker_native.privileged = true - - $compose.services.windmill_worker.environment ++= ["DISABLE_NSJAIL=false"] - $compose.services.windmill_worker_native.environment ++= ["DISABLE_NSJAIL=false"] - } return ($compose | to yaml) } diff --git a/frontend/README_DEV.md b/frontend/README_DEV.md index c5ba2a0c15..03d0145dfa 100644 --- a/frontend/README_DEV.md +++ b/frontend/README_DEV.md @@ -113,8 +113,8 @@ it can build the image and run on local repository. ```bash # Issue the build -docker/dev.nu up --features "python,static_frontend" docker/DockerfileNsjail --rebuild -# Will create and run `main__nsjail__python-static_frontend` +docker/dev.nu up --features "python,static_frontend" --rebuild +# Will create and run `main-python-static_frontend` ``` If you develop wasm parser for new language you can also pass `--wasm-pkg ` and it will include local parser to the image. For more information please see the script directly or run it with `--help` flag.