Skip to content

Publish a prebuilt devcontainer image to GHCR #2136

@kantord

Description

@kantord

Summary

Build the project's devcontainer image (.devcontainer/Dockerfile) on every merge to main and publish it to a GHCR repository (e.g. ghcr.io/stacklok/toolhive-studio-devcontainer:latest and :main). Then have other workflows (and the local pnpm devContainer:dev) pull the published image instead of building from scratch.

Why

The Dockerfile currently builds an image with Node 24 + a long apt list (Xvfb, fluxbox, x11vnc, dbus, gnome-keyring, ImageMagick, xdotool, libsecret, ...). On every CI job that uses the devcontainer the runner spends ~2 minutes on apt-get + image build before any project work can begin. Even with BuildKit's gha cache backend wired up, fetching cache layers from gha is comparable in cost to a fresh apt install.

Numbers from the experiment/bug-fix-visual proof on PR #2120:

  • Cold (no cache): build step = ~118s
  • After buildx + gha-cache populated: build step = ~198s (cache fetch + node_modules postCreate dominate)

A prebuilt image published to GHCR would:

  • Compress to a single docker pull from the runner's region — usually 10–30s.
  • Eliminate the apt and base-image variability across runs.
  • Give local users a faster first-time setup (pnpm devContainer:dev would pull the image instead of building it).

Proposed work

  1. New workflow .github/workflows/publish-devcontainer.yml triggered on push to main paths-filtered to .devcontainer/** (and optionally manual dispatch).
  2. Build with devcontainers/ci@v0.3 configured with imageName: ghcr.io/stacklok/toolhive-studio-devcontainer, cacheFrom: type=gha, push: always so the image is pushed to GHCR on each main build.
  3. Tag the image with both :latest and :<short-sha> so consumers can pin if desired.
  4. Update .devcontainer/devcontainer.json to support pulling the prebuilt image (e.g. via image: for CI use, while keeping build: for local dev customization). Or document a CI-only override.
  5. Update the experimental + future agent workflows to consume the prebuilt image with cacheFrom: registry,ref=ghcr.io/stacklok/toolhive-studio-devcontainer:latest (or use image: directly).

Out of scope

  • Multi-arch images (linux/amd64 only initially; arm64 builds for ToolHive Studio releases are a separate workflow).
  • Non-CI consumption from pnpm devContainer:dev — can land later once the publish path is stable.

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions