|
| 1 | +FROM node:24-bookworm-slim AS node-src |
| 2 | +FROM rhysd/actionlint:1.7.8 AS actionlint-src |
| 3 | +FROM ghcr.io/hadolint/hadolint:v2.14.0-debian AS hadolint-src |
| 4 | +FROM ghcr.io/zizmorcore/zizmor:1.21.0 AS zizmor-src |
| 5 | + |
| 6 | +# Just setting this one up for re-use so it only needs to be updated in one place. |
| 7 | +# Useful in case we add new stages so the same base is used everywhere. |
| 8 | +FROM ubuntu:noble-20260113 AS base-runtime |
| 9 | + |
| 10 | +FROM base-runtime AS dev-runtime |
| 11 | + |
| 12 | +SHELL ["/bin/bash", "-euC", "-o", "pipefail", "-c"] |
| 13 | + |
| 14 | +ARG DEBIAN_FRONTEND=noninteractive |
| 15 | + |
| 16 | +ENV NODE_ENV=development \ |
| 17 | + NPM_CONFIG_PREFIX=/usr/local \ |
| 18 | + PNPM_HOME=/opt/pnpm \ |
| 19 | + PNPM_STORE_PATH=/pnpm-store \ |
| 20 | + PATH="/home/ubuntu/.local/bin:/usr/local/lib/node_modules/bin:/opt/pnpm:/usr/local/go/bin:/usr/local/bin:/usr/bin:${PATH}" |
| 21 | + |
| 22 | +RUN <<EOF |
| 23 | +GLOBAL_NODE_MODULES="/usr/local/lib/node_modules" |
| 24 | +groupadd -r docker |
| 25 | +usermod -aG staff ubuntu |
| 26 | +usermod -aG docker ubuntu |
| 27 | +usermod -aG docker root |
| 28 | +chown -R root:staff /usr/local/bin |
| 29 | +mkdir -p "${GLOBAL_NODE_MODULES}" \ |
| 30 | + "${PNPM_HOME}" \ |
| 31 | + "${PNPM_STORE_PATH}" \ |
| 32 | + /etc/apt/sources.list.d \ |
| 33 | + /etc/apt/keyrings |
| 34 | +chmod 755 /etc/apt/keyrings |
| 35 | +chmod 755 /etc/apt/sources.list.d |
| 36 | +chmod -R 0775 "${PNPM_HOME}" "${GLOBAL_NODE_MODULES}" /usr/local/bin |
| 37 | +chmod -R 0777 "${PNPM_STORE_PATH}" |
| 38 | +chown -R ubuntu:staff "${PNPM_HOME}" "${PNPM_STORE_PATH}" "${GLOBAL_NODE_MODULES}" |
| 39 | +chmod -R g+sw "${PNPM_HOME}" "${PNPM_STORE_PATH}" "${GLOBAL_NODE_MODULES}" |
| 40 | +EOF |
| 41 | + |
| 42 | +# Bring in toolchains/artifacts (optimized with --link) |
| 43 | +COPY --link --from=hadolint-src /bin/hadolint /usr/local/bin/ |
| 44 | +COPY --link --from=zizmor-src /usr/bin/zizmor /usr/local/bin/zizmor |
| 45 | +## Actionlint also has shellcheck in its bin |
| 46 | +COPY --link --from=actionlint-src /usr/local/bin/ /usr/local/bin/ |
| 47 | + |
| 48 | +# Symlink-dependent toolchains (cannot use --link) |
| 49 | +COPY --from=node-src \ |
| 50 | + --chown=0:50 \ |
| 51 | + --exclude=*CHANGELOG.md \ |
| 52 | + --exclude=*README.md \ |
| 53 | + --exclude=bin/docker-entrypoint.sh \ |
| 54 | + /usr/local/ /usr/local/ |
| 55 | +COPY --from=node-src \ |
| 56 | + --chown=0:50 \ |
| 57 | + /opt /opt |
| 58 | + |
| 59 | +RUN --mount=type=cache,target=/var/cache/apt,id=apt-archives,sharing=shared \ |
| 60 | + --mount=type=cache,target=/var/lib/apt/lists,id=apt-lists,sharing=locked \ |
| 61 | + <<EOF |
| 62 | +apt-get update |
| 63 | +apt-get install -y --no-install-recommends \ |
| 64 | + curl \ |
| 65 | + software-properties-common \ |
| 66 | + ca-certificates |
| 67 | +curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null |
| 68 | +chmod 0044 /etc/apt/keyrings/githubcli-archive-keyring.gpg |
| 69 | +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null |
| 70 | +apt-get update |
| 71 | +apt-get install -y --no-install-recommends \ |
| 72 | + gh \ |
| 73 | + git \ |
| 74 | + sudo |
| 75 | + |
| 76 | +# Setup sudo access |
| 77 | +echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ubuntu |
| 78 | +chmod 0440 /etc/sudoers.d/ubuntu |
| 79 | + |
| 80 | +# Global npm configuration |
| 81 | +## This sets config for both root and regular users. |
| 82 | +## Use the heredoc syntax so we also get comments in the image for reference in-use. |
| 83 | +cat > /usr/local/etc/npmrc <<EONPMRC |
| 84 | +## Disable funding messages and automatic audits |
| 85 | +fund=false |
| 86 | +audit=false |
| 87 | +## Prefer the offline modules when possible to speed up installs |
| 88 | +## Particularly useful in CI environments with caching enabled |
| 89 | +prefer-offline=true |
| 90 | +## Help network or registry issues by massaging the network config |
| 91 | +## It is balanced to slowly back off up to the 120ms max on the |
| 92 | +## final attempt. |
| 93 | +## It should go like this: 3.75s, 7.5s, 15s, 30s, 60s, 120s. |
| 94 | +## We politely back-off and delay instead of rushing retries |
| 95 | +## so the registry is not hammered to cause an outage. |
| 96 | +fetch-retries=6 |
| 97 | +fetch-retry-factor=2 |
| 98 | +fetch-retry-mintimeout=3750 |
| 99 | +fetch-retry-maxtimeout=120000 |
| 100 | +## Setup logging to be more efficient for containers |
| 101 | +## Keep the default log level, but discard logs going to a fail. |
| 102 | +loglevel=notice |
| 103 | +logs-dir=/dev/null |
| 104 | +EONPMRC |
| 105 | + |
| 106 | +# Install pnpm globally |
| 107 | +curl -fsSL https://get.pnpm.io/install.sh | \ |
| 108 | + env PNPM_HOME="${PNPM_HOME}" \ |
| 109 | + SHELL=/bin/bash \ |
| 110 | + bash - |
| 111 | + |
| 112 | +# Install GitHub copilot |
| 113 | +curl -fsSL https://gh.io/copilot-install | bash |
| 114 | + |
| 115 | +EOF |
| 116 | + |
| 117 | +WORKDIR /workspace |
0 commit comments