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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions