FROM node:20-trixie # Install golang (Source: https://github.com/docker-library/golang) RUN set -eux; \ arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \ url=; \ case "$arch" in \ 'amd64') \ url='https://dl.google.com/go/go1.25.3.linux-amd64.tar.gz'; \ sha256='0335f314b6e7bfe08c3d0cfaa7c19db961b7b99fb20be62b0a826c992ad14e0f'; \ ;; \ 'arm64') \ url='https://dl.google.com/go/go1.25.3.linux-arm64.tar.gz'; \ sha256='1d42ebc84999b5e2069f5e31b67d6fc5d67308adad3e178d5a2ee2c9ff2001f5'; \ ;; \ *) echo >&2 "error: unsupported architecture '$arch' (likely packaging update needed)"; exit 1 ;; \ esac; \ \ wget -O go.tgz.asc "$url.asc"; \ wget -O go.tgz "$url" --progress=dot:giga; \ echo "$sha256 go.tgz" | sha256sum -c -; \ \ # https://github.com/golang/go/issues/14739#issuecomment-324767697 GNUPGHOME="$(mktemp -d)"; export GNUPGHOME; \ # https://www.google.com/linuxrepositories/ gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 'EB4C 1BFD 4F04 2F6D DDCC EC91 7721 F63B D38B 4796'; \ # let's also fetch the specific subkey of that key explicitly that we expect "go.tgz.asc" to be signed by, just to make sure we definitely have it gpg --batch --keyserver keyserver.ubuntu.com --recv-keys '2F52 8D36 D67B 69ED F998 D857 78BD 6547 3CB3 BD13'; \ gpg --batch --verify go.tgz.asc go.tgz; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME" go.tgz.asc; \ \ tar -C /usr/local -xzf go.tgz; \ rm go.tgz; \ \ /usr/local/go/bin/go version # Install docker CLI RUN set -eux; \ arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \ url=; \ case "$arch" in \ 'amd64') \ url='https://download.docker.com/linux/static/stable/x86_64/docker-28.5.1.tgz'; \ sha256='5c0d19f31fece1accd0358bb8cff591fe25d7b6cba19f0fd412cbfdc07f75ff6'; \ ;; \ 'arm64') \ url='https://download.docker.com/linux/static/stable/aarch64/docker-28.5.1.tgz'; \ sha256='de54e37157f45a43f42f6271302372d95c0eb992cc35ecaee74989bb14058c94'; \ ;; \ *) echo >&2 "error: unsupported architecture '$arch' (likely packaging update needed)"; exit 1 ;; \ esac; \ \ wget -O docker.tgz "$url" --progress=dot:giga; \ echo "$sha256 docker.tgz" | sha256sum -c -; \ tar -xzf docker.tgz; \ mv docker/docker /usr/bin; \ rm -r docker docker.tgz # Install other tools RUN set -eux; \ curl -SsL --output /usr/share/keyrings/thetadev.gpg "https://thetadev.de/repo/thetadev.gpg"; \ echo "9da73052da117dacc9a2affb65716814887728f18f9bb002cf595dd8c5a1191c /usr/share/keyrings/thetadev.gpg" | sha256sum -c; \ echo "deb [signed-by=/usr/share/keyrings/thetadev.gpg] https://thetadev.de/repo universal main\ndeb [signed-by=/usr/share/keyrings/thetadev.gpg] https://thetadev.de/repo bookworm main" > /etc/apt/sources.list.d/thetadev.list; \ dpkg --add-architecture amd64; \ dpkg --add-architecture arm64; \ apt-get update; \ apt-get upgrade -y; \ apt-get install -y --no-install-recommends sudo python-is-python3 python3-pip python3-poetry nano tree zip zstd brotli zopfli jq yq golangci-lint \ rustup cargo-audit cargo-deny cargo-sqlx cargo-nextest git-cliff just task pre-commit mdbook shellcheck ffmpeg postgresql-client uv deno \ libssl-dev:amd64 libssl-dev:arm64; \ \ arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \ case "$arch" in \ 'amd64') \ apt-get install -y gcc-aarch64-linux-gnu; \ ;; \ 'arm64') \ apt-get install -y gcc-x86-64-linux-gnu; \ ;; \ *) echo >&2 "error: unsupported architecture '$arch'"; exit 1 ;; \ esac; \ \ apt-get clean; \ printf 'fund=false\nupdate-notifier=false' > /root/.npmrc; \ npm install -g pnpm tsx; \ install -d -o 1000 -g 1000 /opt/hostedtoolcache # User setup RUN userdel -r node && useradd -m ci && echo 'ci ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers USER ci # Install Rust RUN set -eux; \ rustup install stable; \ rustup target add x86_64-unknown-linux-gnu x86_64-unknown-linux-musl aarch64-unknown-linux-gnu aarch64-unknown-linux-musl # User account setup RUN set -eux; \ gpg --batch --keyserver keys.openpgp.org --recv-keys 86b02e72397343b766f005dd649ca4ebdc338394; \ echo -e "5\ny\n" | gpg --no-tty --command-fd=0 --edit-key 86b02e72397343b766f005dd649ca4ebdc338394 trust; \ git config --global user.name "Forgejo Actions"; \ git config --global user.email "forgejo.actions@example.com"; \ git config --global init.defaultBranch main; \ mkdir -p /home/ci/.cargo /home/ci/.config; \ arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \ case "$arch" in \ 'amd64') \ printf '[target.aarch64-unknown-linux-gnu]\nlinker = "aarch64-linux-gnu-gcc"' > /home/ci/.cargo/config.toml; \ ;; \ 'arm64') \ printf '[target.x86_64-unknown-linux-gnu]\nlinker = "x86_64-linux-gnu-gcc"' > /home/ci/.cargo/config.toml; \ ;; \ *) echo >&2 "error: unsupported architecture '$arch'"; exit 1 ;; \ esac; \ printf 'fund=false\nupdate-notifier=false' > /home/ci/.npmrc; \ printf '[profile.ci]\nfailure-output = "immediate-final"\nfail-fast = false\n\n[profile.ci.junit]\npath = "junit.xml"' > /home/ci/.config/nextest.toml; ENV PATH=/usr/local/go/bin:/home/ci/go/bin:/home/ci/.cargo/bin:$PATH ENV NEXTEST_PROFILE=ci ENTRYPOINT /usr/bin/bash