stacklok / stacklok/toolhive-studio

Publish a prebuilt devcontainer image to GHCR

Open
#2,136 0 comments 0 reactions 1 assignee View on GitHub

@kantord is already working on this.

Since Apr 28, 2026.

Dominant language
TypeScript
Stars
167
Forks
24
Avg merge
11h 32m
Merged PRs (30d)
91

Description

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

  • PR #2120 — devcontainer-in-CI proof; node_modules cache is being added in that PR but the apt/base-image build cost remains, which a prebuilt image would address.
  • Issue #2129 — CDP support in the devcontainer; orthogonal but lives in the same .devcontainer/Dockerfile.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.