mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: bake mise tools into a shared dir on dogfood image (#25387)
Three changes to make mise-managed tooling reach every dogfood workspace cleanly, with the upstream `devcontainers-cli` module fix as the original trigger. ## Why the module breaks The upstream [`devcontainers-cli` coder module](https://github.com/coder/registry/blob/main/registry/coder/modules/devcontainers-cli/run.sh) does `npm install -g @devcontainers/cli` and then verifies the binary is on `PATH`. With mise-managed Node (introduced in #25282), `npm install -g` lands the binary at `$MISE_DATA_DIR/installs/node/<ver>/bin/`, which is *not* on `PATH` and which `mise reshim` does not surface as a shim. The post-install check fails: ``` Installing @devcontainers/cli using npm... changed 1 package in 661ms Reshimming mise 26... Installation completed but 'devcontainer' command not found in PATH ``` Even though nothing the user does is actually broken. ## What this PR does 1. **`mise.toml`** — pre-install `@devcontainers/cli` via mise's `npm:` backend (`npm:@devcontainers/cli = "0.87.0"`). The mise shim lands at `$MISE_DATA_DIR/shims/devcontainer`, on `PATH`. The upstream module's `run.sh` short-circuits on its `command -v devcontainer` check and exits 0 without ever running the broken npm-install path. Strictly redundant after fix the second point makes `npm i -g` work natively, but kept for build-time pre-install and pinned-version reasons matching the other mise-pinned CLIs. 2. **`dogfood/coder/ubuntu-*.04/Dockerfile`** — set `NPM_CONFIG_PREFIX=/home/coder/.npm-global` and prepend `/home/coder/.npm-global/bin` to `PATH`. With this, generic `npm install -g <pkg>` (prettier, biome, anything frontend folks reach for) lands in a stable home-volume dir that is already on `PATH`, survives node version bumps, and needs no `mise reshim`. The mise `npm:` backend keeps using its own `--prefix` internally so the `npm:@devcontainers/cli` pin still installs under `$MISE_DATA_DIR` as before. 3. **`dogfood/coder/ubuntu-*.04/Dockerfile`** — install image tools into `/opt/mise/data` at build time (owned by `coder`) and expose them at runtime via `MISE_SHARED_INSTALL_DIRS=/opt/mise/data/installs`, keeping `MISE_DATA_DIR=/home/coder/.local/share/mise` for the user's own installs. This decouples baked tool versions from the home volume's copy-on-first-mount: fresh and existing workspaces both immediately see the image's tool set without a `mise install` step, and the user's own `mise install <tool>` / `mise use --global` still lands on the home volume. The `/opt/mise/data/shims` dir trails the user shim dir on `PATH` so a user-installed version wins when both exist. Pinned to `0.87.0` (current latest) so Renovate/Dependabot can bump deliberately, matching the policy applied to the other floating tools during the mise migration (`lazygit`, `doctl`, `jj`, `typos`, `watchexec`). --------- Signed-off-by: Thomas Kosiewski <tk@coder.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -205,18 +205,20 @@ RUN install --directory --mode=0755 /etc/mise
|
||||
COPY --chmod=0644 mise.toml /etc/mise/config.toml
|
||||
COPY --chmod=0644 mise.lock /etc/mise/mise.lock
|
||||
|
||||
# Pre-install image tools as coder so they land on the home volume
|
||||
# layer. Sudo drops env vars, so MISE_* are re-exported via `env`.
|
||||
# github_token (optional build secret) authenticates aqua's API
|
||||
# calls; without it builds may hit GitHub's 60/hr unauth limit.
|
||||
# Pre-install tools into /opt/mise/data so they survive the home
|
||||
# volume's copy-on-first-mount. MISE_SHARED_INSTALL_DIRS (set below)
|
||||
# exposes them at runtime; MISE_DATA_DIR stays on the home volume.
|
||||
# github_token authenticates aqua's API calls (optional secret).
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /opt/mise /opt/mise/data
|
||||
RUN --mount=type=secret,id=github_token,required=false \
|
||||
gh_token="$(cat /run/secrets/github_token 2>/dev/null || true)" && \
|
||||
sudo --user=coder env \
|
||||
"MISE_DATA_DIR=$MISE_DATA_DIR" \
|
||||
"MISE_DATA_DIR=/opt/mise/data" \
|
||||
"MISE_TRUSTED_CONFIG_PATHS=$MISE_TRUSTED_CONFIG_PATHS" \
|
||||
"GITHUB_TOKEN=$gh_token" \
|
||||
/usr/local/bin/mise install --yes && \
|
||||
PATH="$MISE_DATA_DIR/shims:$PATH" pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
PATH="/opt/mise/data/shims:$PATH" MISE_DATA_DIR=/opt/mise/data pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
rm -rf /opt/mise/data/cache /opt/mise/data/downloads && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Homebrew as the coder user so the supported Linux prefix remains
|
||||
@@ -237,7 +239,13 @@ USER coder
|
||||
ENV HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew" \
|
||||
HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar" \
|
||||
HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
|
||||
ENV PATH="${MISE_DATA_DIR}/shims:${HOMEBREW_PREFIX}/bin:${HOMEBREW_PREFIX}/sbin:/home/coder/go/bin:${PATH}"
|
||||
# Pin npm globals to a stable home dir, otherwise they land in
|
||||
# mise's version-specific node bin dir which isn't on PATH.
|
||||
ENV NPM_CONFIG_PREFIX="/home/coder/.npm-global"
|
||||
# Baked shims trail user shims on PATH so user installs win when
|
||||
# both exist.
|
||||
ENV MISE_SHARED_INSTALL_DIRS="/opt/mise/data/installs"
|
||||
ENV PATH="/home/coder/.npm-global/bin:${MISE_DATA_DIR}/shims:/opt/mise/data/shims:${HOMEBREW_PREFIX}/bin:${HOMEBREW_PREFIX}/sbin:/home/coder/go/bin:${PATH}"
|
||||
|
||||
# Override CARGO_HOME so cargo registry/cache writes go to the coder
|
||||
# user's home directory instead of the root-owned /usr/local/cargo.
|
||||
|
||||
@@ -215,18 +215,20 @@ RUN install --directory --mode=0755 /etc/mise
|
||||
COPY --chmod=0644 mise.toml /etc/mise/config.toml
|
||||
COPY --chmod=0644 mise.lock /etc/mise/mise.lock
|
||||
|
||||
# Pre-install image tools as coder so they land on the home volume
|
||||
# layer. Sudo drops env vars, so MISE_* are re-exported via `env`.
|
||||
# github_token (optional build secret) authenticates aqua's API
|
||||
# calls; without it builds may hit GitHub's 60/hr unauth limit.
|
||||
# Pre-install tools into /opt/mise/data so they survive the home
|
||||
# volume's copy-on-first-mount. MISE_SHARED_INSTALL_DIRS (set below)
|
||||
# exposes them at runtime; MISE_DATA_DIR stays on the home volume.
|
||||
# github_token authenticates aqua's API calls (optional secret).
|
||||
RUN install --directory --owner=coder --group=coder --mode=0755 /opt/mise /opt/mise/data
|
||||
RUN --mount=type=secret,id=github_token,required=false \
|
||||
gh_token="$(cat /run/secrets/github_token 2>/dev/null || true)" && \
|
||||
sudo --user=coder env \
|
||||
"MISE_DATA_DIR=$MISE_DATA_DIR" \
|
||||
"MISE_DATA_DIR=/opt/mise/data" \
|
||||
"MISE_TRUSTED_CONFIG_PATHS=$MISE_TRUSTED_CONFIG_PATHS" \
|
||||
"GITHUB_TOKEN=$gh_token" \
|
||||
/usr/local/bin/mise install --yes && \
|
||||
PATH="$MISE_DATA_DIR/shims:$PATH" pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
PATH="/opt/mise/data/shims:$PATH" MISE_DATA_DIR=/opt/mise/data pnpm dlx playwright@1.47.0 install --with-deps chromium && \
|
||||
rm -rf /opt/mise/data/cache /opt/mise/data/downloads && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Homebrew as the coder user so the supported Linux prefix remains
|
||||
@@ -247,7 +249,13 @@ USER coder
|
||||
ENV HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew" \
|
||||
HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar" \
|
||||
HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
|
||||
ENV PATH="${MISE_DATA_DIR}/shims:${HOMEBREW_PREFIX}/bin:${HOMEBREW_PREFIX}/sbin:/home/coder/go/bin:${PATH}"
|
||||
# Pin npm globals to a stable home dir, otherwise they land in
|
||||
# mise's version-specific node bin dir which isn't on PATH.
|
||||
ENV NPM_CONFIG_PREFIX="/home/coder/.npm-global"
|
||||
# Baked shims trail user shims on PATH so user installs win when
|
||||
# both exist.
|
||||
ENV MISE_SHARED_INSTALL_DIRS="/opt/mise/data/installs"
|
||||
ENV PATH="/home/coder/.npm-global/bin:${MISE_DATA_DIR}/shims:/opt/mise/data/shims:${HOMEBREW_PREFIX}/bin:${HOMEBREW_PREFIX}/sbin:/home/coder/go/bin:${PATH}"
|
||||
|
||||
# Override CARGO_HOME so cargo registry/cache writes go to the coder
|
||||
# user's home directory instead of the root-owned /usr/local/cargo.
|
||||
|
||||
Reference in New Issue
Block a user