Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

dock

Lean, layered CI Docker images published at ghcr.io/driftsys/dock and Docker Hub.

Each image adds exactly one concern — scripting foundation, compilation toolchain, or language runtime — so teams pick the smallest image that covers their pipeline.

Why dock?

  • Small — Alpine-based images start at ~32 MB (vs ~600 MB for typical CI images).
  • Layered — every image inherits from :core, so all pipelines share the same scripting tools (git, curl, jq, yq, gpg, …).
  • Multi-arch — every image ships for linux/amd64 and linux/arm64.
  • Dual-variant — Alpine (musl, default) and Debian (glibc) for each image.
  • Inspectable — each image records installed tool versions in /etc/dock/manifest.json.

Image catalog

ImageFromSize (Alpine)Contents
:corealpine~32 MBShell, Git, curl, jq, yq, gpg
:rust:core~260 MBRust stable, cargo, clippy, rustfmt
:deno:core~120 MBDeno runtime
:node:core~115 MBNode.js LTS, npm
:python:core~55 MBPython 3, pip, ruff
:polyglot:rust~382 MBRust + Deno + Python 3
:lint:core~44 MBshellcheck, editorconfig-checker, git-std

Inheritance tree

alpine:3.21
  └── :core              (~32 MB)
      ├── :rust          (~260 MB)
      │   └── :polyglot  (~382 MB)
      ├── :deno          (~120 MB)
      ├── :node          (~115 MB)
      ├── :python        (~55 MB)
      └── :lint          (~44 MB, amd64 only)

Getting Started

Pull an image

Images are available from both GHCR and Docker Hub:

# From GitHub Container Registry (default)
docker pull ghcr.io/driftsys/dock:core

# From Docker Hub
docker pull driftsys/dock:core

Both registries publish the same images with identical digests.

Run interactively

docker run --rm -it ghcr.io/driftsys/dock:core bash

Use in GitHub Actions

jobs:
  build:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:rust
    steps:
      - uses: actions/checkout@v4
      - run: cargo build --release
      - run: cargo test

Use in GitLab CI

build:
  image: ghcr.io/driftsys/dock:rust
  script:
    - cargo build --release
    - cargo test

Choose a variant

Every image ships in two variants:

TagBaselibcBest for
:imagealpine:3.21muslSmallest footprint, default
:image-debiandebian:bookworm-slimglibcBroader compatibility

Use the Debian variant when your tools require glibc (e.g. pre-built binaries that don’t support musl).

Pin a version

Floating tags (:core, :rust, …) always point to the latest release. For reproducible builds, pin to a version tag:

container: ghcr.io/driftsys/dock:rust-0.1.0

Inspect the manifest

Each image records installed tool versions in /etc/dock/manifest.json:

docker run --rm ghcr.io/driftsys/dock:rust \
  jq . /etc/dock/manifest.json
{
  "image": "rust",
  "version": "0.1.0",
  "tools": {
    "rustc": "1.83.0",
    "cargo": "1.83.0",
    "clippy": "0.1.83",
    "rustfmt": "1.8.0"
  }
}

Next steps

Extending dock images

All dock images are toolboxes with no CMD or ENTRYPOINT. Adding packages on top is straightforward.

Adding an apk package (Alpine)

FROM ghcr.io/driftsys/dock:core

# hadolint ignore=DL3018
RUN apk add --no-cache sqlite

Adding an apt package (Debian)

FROM ghcr.io/driftsys/dock:core-debian

# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends sqlite3 \
 && rm -rf /var/lib/apt/lists/*

Adding a Cargo tool (on top of :rust)

FROM ghcr.io/driftsys/dock:rust

RUN cargo install cargo-nextest --locked

Pinning a runtime version

All runtime images accept build arguments for version pinning:

# Build a Deno image with a specific version
docker buildx build \
  --build-arg DENO_VERSION=2.0.0 \
  -f images/deno/Dockerfile .

Multi-stage builds

Use dock images in the build stage; copy artifacts to a minimal final image:

FROM ghcr.io/driftsys/dock:rust AS builder
WORKDIR /src
COPY . .
RUN cargo build --release

FROM alpine:3.21
COPY --from=builder /src/target/release/myapp /usr/local/bin/

Versioning strategy

Tag format

ghcr.io/driftsys/dock:{image}-{variant}-{version}
  • {image}core, rust, deno, node, python, polyglot
  • {variant} — omitted for Alpine (default); -debian for the Debian variant
  • {version} — semantic version tag, e.g. v1.2.3

Examples

ghcr.io/driftsys/dock:core           # latest Alpine core
ghcr.io/driftsys/dock:core-v1.2.3   # pinned Alpine core
ghcr.io/driftsys/dock:rust-debian    # latest Debian rust

Floating tags

Floating tags (:core, :rust, …) always point to the latest release. Use them in prototyping; pin to a version tag in production.

Semantic versioning

Releases follow Semantic Versioning:

ChangeBump
Breaking change (tool removed, API changed)major
New tool added, runtime upgrademinor
Bug fix, security patchpatch

Runtime pinning

Runtime versions are recorded in /etc/dock/manifest.json inside each image — not in the image tag. Inspect them with:

docker run --rm ghcr.io/driftsys/dock:rust \
  jq . /etc/dock/manifest.json

To pin a specific runtime version, use the --build-arg override at build time (see extending.md).

Rebuild strategy

Images are rebuilt on every release tag (v*). The OS base (alpine:3.21, debian:bookworm-slim) is resolved at build time. All installed packages reflect the state of the package index at release time.

Security patches to the base OS are incorporated by cutting a new release. Dependabot is configured to notify when referenced base images have known CVEs.

:core

Foundation image for all dock images. Contains the scripting and data tools every CI pipeline needs.

Base images

VariantBase
Alpine (default)alpine:3.21
Debiandebian:bookworm-slim

Installed packages

ToolAlpine packageDebian packagePurpose
bashbashbashShell
curlcurlcurlHTTP client
gitgitgitVersion control
git-lfsgit-lfsgit-lfsLarge file storage
gpggnupggnupgSignature verification
jqjqjqJSON processor
yqyq-gobinary installYAML/TOML/JSON processor
envsubstgettextgettext-baseEnvironment variable substitution
dotenvdotenvshell script.env file loader
sshopenssh-clientopenssh-clientSSH client
patchpatchpatchFile patching
findfindutilsfindutilsFile search
treetreetreeDirectory listing
diffdiffutilsdiffutilsFile comparison
zip / unzipzip, unzipzip, unzipArchive tools
tzdatatzdatatzdataTimezone data
coreutilscoreutilscoreutilsGNU core utilities
ca-certificatesca-certificatesca-certificatesTLS root certificates

Runtime manifest

docker run --rm ghcr.io/driftsys/dock:core jq . /etc/dock/manifest.json

Approximate size

  • Alpine: ~32 MB
  • Debian: ~80 MB

:rust

Rust compilation toolchain. Inherits all :core tools.

Base

FROM ghcr.io/driftsys/dock:core (via build context)

Installed tools

ToolInstall methodPurpose
rustc, cargorustup stableRust compiler and package manager
clippyrustup componentLinter
rustfmtrustup componentFormatter
cargo-auditcargo install --lockedSecurity advisory scanner
cargo-denycargo install --lockedDependency policy checker
gcc, g++apk (Alpine)C/C++ compiler for build scripts
musl-devapkmusl libc headers
pkg-configpkgconf (apk)Build configuration helper
openssl-devapkOpenSSL headers for Rust crates

Usage in CI

jobs:
  test:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:rust
    steps:
      - uses: actions/checkout@v4
      - run: cargo test
      - run: cargo clippy -- -D warnings
      - run: cargo audit

Approximate size

~260 MB (Alpine)

:deno

Deno runtime. Inherits all :core tools.

Base

FROM ghcr.io/driftsys/dock:core (via build context)

Installed tools

ToolInstall methodPurpose
denoofficial static binaryTypeScript/JavaScript runtime

Deno is installed from the official GitHub release binary. The version is controlled by the DENO_VERSION build argument.

Usage in CI

jobs:
  check:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:deno
    steps:
      - uses: actions/checkout@v4
      - run: deno lint
      - run: deno fmt --check
      - run: deno test

Build arguments

ArgumentDefaultDescription
DENO_VERSION2.3.1Deno release to install

Approximate size

~120 MB (Alpine)

:node

Node.js LTS runtime. Inherits all :core tools.

Base

FROM ghcr.io/driftsys/dock:core (via build context)

Installed tools

ToolInstall methodPurpose
nodeapk (nodejs)Node.js LTS runtime
npmapk (npm)Package manager

Usage in CI

jobs:
  build:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:node
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

Approximate size

~115 MB (Alpine)

:python

Python 3 runtime with ruff. Inherits all :core tools.

Base

FROM ghcr.io/driftsys/dock:core (via build context)

Installed tools

ToolInstall methodPurpose
python3apkPython 3 interpreter
pipapk (py3-pip)Package installer
ruffpipLinter and formatter

Usage in CI

jobs:
  lint:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:python
    steps:
      - uses: actions/checkout@v4
      - run: ruff check .
      - run: ruff format --check .

Approximate size

~55 MB (Alpine)

:polyglot

All-in-one image for mixed-language pipelines. Inherits all :rust tools (which include all :core tools), and adds Deno and Python 3.

Base

FROM ghcr.io/driftsys/dock:rust (via build context)

Installed tools

Includes everything from :rust plus:

ToolInstall methodPurpose
denoofficial static binaryTypeScript/JavaScript runtime
python3apkPython 3 interpreter
pipapk (py3-pip)Package installer
ruffpipLinter and formatter

Use case: Deno FFI with Rust

The polyglot image supports Deno’s Foreign Function Interface (FFI) to call Rust-compiled shared libraries:

// Compile: cargo build --release --lib
const lib = Deno.dlopen("libmylib.so", {
  my_fn: { parameters: ["i32"], result: "i32" },
});
console.log(lib.symbols.my_fn(42));
lib.close();

Usage in CI

jobs:
  interop:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:polyglot
    steps:
      - uses: actions/checkout@v4
      - run: cargo build --release --lib
      - run: deno run --allow-ffi --unstable-ffi main.ts

Approximate size

~382 MB (Alpine)

:lint

Linting toolbox. Inherits all :core tools.

Base

FROM ghcr.io/driftsys/dock:core (via build context)

Installed tools

ToolInstall methodPurpose
shellcheckapkShell script linter
editorconfig-checkerapkEditorConfig rule checker
git-stdbinary (GitHub releases)Conventional commits + git hooks

Platform note

git-std releases only provide a Linux x86_64 binary. This image is therefore built for linux/amd64 only.

Usage in CI

jobs:
  lint:
    runs-on: ubuntu-latest
    container: ghcr.io/driftsys/dock:lint
    steps:
      - uses: actions/checkout@v4
      - run: shellcheck scripts/*.sh
      - run: editorconfig-checker
      - run: git std check

Build arguments

ArgumentDefaultDescription
GIT_STD_VERSION0.7.0git-std release to install

Approximate size

~44 MB (Alpine, linux/amd64 only)