From dc63ed66f1a651260ccc7df3fd497c1ab93438b5 Mon Sep 17 00:00:00 2001 From: "claude@clouddev1" Date: Fri, 12 Jun 2026 21:08:04 +0000 Subject: [PATCH] ci: nix CI toolchain image (node-slim base + warmed flake) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Job-container image the gate runs in. node:22-bookworm-slim satisfies the act_runner contract (sleep/bash/node) far more cheaply than the catthehacker images; single-user nix installed on top (pre-create /nix + empty build-users-group so it installs as root in a container) with the flake's devShell pre-warmed — CI enters a ready 1.95.0 toolchain in ~1.4s. Verified by local build. ~5.5GB (rust toolchain closure); dep/ target caching is a noted follow-up. --- .gitea/ci-image/Dockerfile | 65 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .gitea/ci-image/Dockerfile diff --git a/.gitea/ci-image/Dockerfile b/.gitea/ci-image/Dockerfile new file mode 100644 index 0000000..161a02a --- /dev/null +++ b/.gitea/ci-image/Dockerfile @@ -0,0 +1,65 @@ +# CI toolchain image for rdbms-playground. +# +# Purpose: a SMALL job-container image that +# (a) satisfies the Gitea act_runner job-container contract — /bin/sleep (the +# keep-alive entrypoint), bash (run: steps), node (JS actions such as +# actions/checkout); a bare nixos/nix image has none of these and won't +# even start (verified by the ci-probe run: "/bin/sleep: no such file"); and +# (b) carries the project's pinned nix toolchain with the flake's devShell +# pre-warmed, so CI runs `nix develop -c cargo ...` against a warm store. +# +# Base: node:22-bookworm-slim. Debian slim already provides bash + coreutils +# (sleep); the node tag adds the actions runtime. Far smaller than the +# catthehacker runner images (which bundle a whole GitHub-runner emulation we +# don't need). +FROM node:22-bookworm-slim + +# nix install + flake eval needs these. git because flakes prefer a VCS context +# and tools shell out to it. Drop apt lists to keep the layer small. +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + curl xz-utils ca-certificates git \ + && rm -rf /var/lib/apt/lists/* + +# Single-user nix (--no-daemon): store at /nix owned by root, no daemon/systemd +# needed — the correct mode for a container. The official installer refuses root +# and shells out to `sudo` purely to create /nix; pre-creating it ourselves (we +# ARE root) sidesteps both. Enable flakes globally so every nix invocation (and +# the runner's steps) get nix-command + flakes without flags. +# nix.conf is written FIRST so the installer's own `nix-env` profile step reads +# it: `build-users-group =` (empty) makes single-user nix build as the calling +# user (root) instead of demanding the nixbld group/users a daemon install would +# create; flakes are enabled globally in the same file. +RUN mkdir -m 0755 /nix && chown root:root /nix \ + && mkdir -p /etc/nix \ + && printf 'build-users-group =\nexperimental-features = nix-command flakes\n' > /etc/nix/nix.conf \ + && curl --proto '=https' --tlsv1.2 -sSf -L https://nixos.org/nix/install -o /tmp/nix-install.sh \ + && sh /tmp/nix-install.sh --no-daemon \ + && rm /tmp/nix-install.sh +ENV PATH=/root/.nix-profile/bin:/nix/var/nix/profiles/default/bin:$PATH +# We set PATH directly instead of sourcing the profile, so also point nix at the +# Debian CA bundle (already installed) for substituter HTTPS — otherwise the +# profile-provided NIX_SSL_CERT_FILE is missing and store downloads fail. +ENV NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt + +# Warm the flake's devShell into the store: realizes nixpkgs + the pinned Rust +# toolchain (rustc/cargo/clippy/rustfmt) + cargo-sweep. Only the inputs that +# determine the shell are copied, so this expensive layer is cached and only +# re-runs when the flake or the toolchain pin changes — not on every source edit. +# (devShell eval is lazy: packages.default — and thus Cargo.toml/Cargo.lock — is +# never forced here, so it needn't be present.) +WORKDIR /warm +COPY flake.nix flake.lock rust-toolchain.toml ./ +RUN nix develop -c rustc --version \ + && nix develop -c cargo --version \ + && nix develop -c cargo clippy --version \ + && nix develop -c cargo fmt --version \ + && nix develop -c cargo sweep --version +WORKDIR / +RUN rm -rf /warm + +# FOLLOW-UP optimisation (intentionally NOT done here, see CI notes): cargo +# dependency + target caching. Each CI run still compiles the ~296-crate graph +# from scratch and pulls crate sources from crates.io. A later pass can bake +# `cargo fetch` (offline crate sources) and/or a warmed target dir, or wire +# sccache, to cut run time. Correctness/first-green first; speed next.