This repository contains Dockerfiles for custom Docker images hosted on GitHub Container Registry (ghcr.io).
New here? The wiki has a guide to picking an image and explains what latest means and when it moves.
- claude-code - Shared Claude Code devcontainer image (default + sandbox variants)
- bun - Bun development container
- claude-bun - Claude Code development container with firewall sandbox
- hugo-bun - Hugo Extended + Bun development container
- hugo-bun-node - Hugo Extended + Bun + Node.js development container (Cloudflare Workers)
- ralphex-fe - Bun + Hugo Extended on ralphex base (standalone image)
Cross-image guides and host-level procedures live in the wiki, because they go stale when Docker or GitHub changes rather than when this repo does.
- Choosing an Image - which of the six images you want
- Image Tags and Rebuild Policy - what
latestmeans, which tags are immutable, when rebuilds happen - Troubleshooting - symptoms that span more than one image
- Docker Disk Maintenance - commands for "low disk space", a hung Docker, and safe cleanup
- Incident: Docker Disk Exhaustion (2026-09-07) - what actually grows, why, and the settings that prevent an outage
- Branch Protection and Renovate Auto-Merge - maintainer runbook
Each subdirectory represents a Docker image project. Devcontainer images use the following structure:
image-name/
├── .devcontainer/
│ ├── Dockerfile # Source of truth for the image
│ └── devcontainer.json # Dev container configuration (uses "build")
└── ...
Standalone Docker images (like ralphex-fe) use a flat structure:
image-name/
├── Dockerfile # Image definition
└── README.md # Image documentation
Shared devcontainer base image for Claude Code projects. Two variants from a single multi-stage Dockerfile: default (full dev environment with agent-browser) and sandbox (network-restricted with iptables firewall). Projects consume pre-built images and control tool versions via .mise.toml. Rebuilds when its pinned tools receive a new release (managed by Renovate), not on a schedule.
Usage in other projects:
See the claude-code README for full setup guide.
Bun development container for modern JavaScript/TypeScript development.
Usage in other projects:
{
"image": "ghcr.io/<username>/devcontainers/bun:latest"
}Claude Code development container with Bun runtime, Claude Code CLI, and a restrictive firewall sandbox.
Usage in other projects:
{
"image": "ghcr.io/<username>/devcontainers/claude-bun:latest",
"runArgs": ["--cap-add=NET_ADMIN", "--cap-add=NET_RAW"],
"postStartCommand": "sudo /usr/local/bin/init-firewall.sh"
}Hugo development container with Bun runtime.
Usage in other projects:
{
"image": "ghcr.io/<username>/devcontainers/hugo-bun:latest"
}Hugo development container with Bun runtime and Node.js LTS for Cloudflare Workers support.
Usage in other projects:
{
"image": "ghcr.io/<username>/devcontainers/hugo-bun-node:latest"
}Standalone Docker image based on ralphex with Bun 1.3.9, Hugo Extended 0.155.3, and Chromium for modern JavaScript/TypeScript development, static site generation, and end-to-end testing.
Usage:
# Pull and run interactively
docker pull ghcr.io/<username>/devcontainers/ralphex-fe:latest
docker run -it --rm -v $(pwd):/workspace -w /workspace ghcr.io/<username>/devcontainers/ralphex-fe:latest
# Run Bun commands
docker run --rm -v $(pwd):/workspace -w /workspace ghcr.io/<username>/devcontainers/ralphex-fe:latest bun run index.ts
# Run Hugo commands
docker run --rm -v $(pwd):/workspace -w /workspace -p 1313:1313 ghcr.io/<username>/devcontainers/ralphex-fe:latest hugo server --bind 0.0.0.0
- Create a new directory with your image name (e.g.,
myimage/) - Add
.devcontainer/Dockerfilewith your image definition - Add
.devcontainer/devcontainer.jsonthat references the Dockerfile - Create a GitHub Actions workflow for the image
- Update this README with usage instructions
- Create a new directory with your image name (e.g.,
myimage/) - Add
Dockerfiledirectly in the directory (no.devcontainer/subdirectory) - Add
README.mdwith image documentation - Create a GitHub Actions workflow for the image
- Update this README with usage instructions
Images from this repository are built and published to GitHub Container Registry. Other projects can reference these images in their devcontainer.json files using the "image" property.
The agent tooling in the claude-code and ralphex-fe images — rtk, ralphex, the Claude Code
CLI, agent-browser, and the gh-stack extension — is pinned as ARGs carrying # renovate:
annotations. Renovate watches their releases and opens a single grouped bump PR when one ships; CI
verifies it, it auto-merges, and that merge rebuilds the affected images. No upstream release means no
PR and no rebuild. Scope and grouping live in .github/renovate.json5;
the Dependency Dashboard issue tracks what is pending. Everything else — including base images and
Bun/Hugo — stays manual.
Setup requirement — Mend portal toggles. Installing the Renovate app with "All repositories" makes Mend default the repo to Silent mode (
dryRun=lookup), where it scans and shows updates in the developer portal but opens no PRs and creates no issues — not even the Dependency Dashboard, and not even a config-warning issue. The symptom is a correct config that appears to do nothing. In the portal, under Repo Engine Settings → Dependency Updates, set:
Toggle Value Silent mode off Automated PRs on Require config file on — with an all-repositories install, this is what keeps Renovate off repos that have no config Create onboarding PRs off — this repo already has a config, so no onboarding PR is needed Setting
modeinrenovate.json5cannot substitute for the Silent-mode toggle, becausedryRuntakes precedence overmodeand is admin-level.
Every image has a workflow_dispatch trigger, so a rebuild can be forced without a code change:
# Rebuild one image from current master
gh workflow run build-ralphex-fe.yml
# Check status / watch
gh run list --workflow=build-ralphex-fe.yml
gh run watchTo change a pinned version, edit the ARG in that image's Dockerfile and open a PR — the merge
triggers the build. There is no longer a workflow that rewrites Dockerfiles and pushes to master.
Install GitHub CLI:
# macOS
brew install gh
# Authenticate (one-time setup)
gh auth login