A small Debian-based devcontainer image for day-to-day development.
It ships with a sensible interactive shell setup and a small toolset for containerized development:
fishas the default shellmisefor tool management and task orchestrationsudowith a passwordlessdevusergit,curl, andopenssh-clienttailscale
Published images are built for linux/amd64 and linux/arm64, signed with keyless Cosign, and include an SBOM.
This repository is the source for the published image at ghcr.io/lauritsk/devcontainer.
It is meant to be:
- small enough to understand and maintain
- predictable for both local use and CI
- easy to consume from VS Code / Dev Containers
- reproducible through
mise-managed checks and release tasks
The image currently:
- starts from a pinned Debian 13 base image
- creates a non-root
devuser with UID/GID1000 - sets
/home/devas the working directory - uses
fishas the login shell - enables passwordless sudo for the
devuser - activates
miseautomatically infish
A minimal .devcontainer/devcontainer.json can point at a published image directly:
{
"name": "devcontainer",
"image": "ghcr.io/lauritsk/devcontainer:0.2.0",
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
}
}The repository itself uses this shape, with extra persistent mounts for mise data and cache:
{
"name": "devcontainer",
"image": "ghcr.io/lauritsk/devcontainer:0.2.0@sha256:ba053b40ae21b5f3c4f3b9d80967b1639242c1a6a0a07c61794eb4a2e68dd16d",
"features": {
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
},
"mounts": [
"source=devcontainer-mise-data,target=/home/dev/.local/share/mise,type=volume",
"source=devcontainer-mise-cache,target=/home/dev/.cache/mise,type=volume"
]
}Tip
Prefer pinning a released tag and digest in consumer repositories for repeatable environments.
This project uses mise for tooling, checks, and release automation.
Common commands:
mise run setup
mise run lint
mise run build
mise run test
mise run audit
mise run check| Command | Purpose |
|---|---|
mise run build |
Build the image locally as localhost/devcontainer:latest |
mise run test |
Run a smoke test against the built image |
mise run audit |
Scan the image and repository for high/critical issues |
mise run check |
Run the main project quality gates |
mise run release:check |
Validate GoReleaser configuration |
mise run release:verify |
Run a snapshot release from a clean worktree |
mise run sbom |
Generate an SBOM for the repository |
Releases are driven by Conventional Commits and Cocogitto.
mise run release:versionThat creates the next Git tag. Pushing the resulting v* tag triggers GitHub Actions to publish:
- multi-arch container images to
ghcr.io/lauritsk/devcontainer - container signatures via Cosign keyless signing
- release artifacts and metadata via GoReleaser
Note
Git tags use the form vX.Y.Z, while published container tags use X.Y.Z.
Published images are signed with GitHub Actions OIDC and Cosign.
cosign verify ghcr.io/lauritsk/devcontainer:X.Y.Z \
--certificate-identity "https://github.com/lauritsk/devcontainer/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"GitHub Actions runs:
mise run checkon pushes and pull requestsmise run release:verifyas a release dry-run checkmise run releaseon pushedv*tags
The published image metadata is defined in .goreleaser.yaml, including:
- OCI labels
- supported platforms
- SBOM generation
- Cosign signing