Skip to content

ADR Guard container image

ADR Guard is published as a multi-platform OCI container image in two registries:

  • GitHub Container Registry (GHCR): ghcr.io/rodri-oliveira-dev/adr-guard
  • Docker Hub: docker.io/rodrigodotnet/adr-guard

Both registries receive the same release build for linux/amd64 and linux/arm64.

Stable releases publish four tag levels:

1.2.3
1.2
1
latest

For reproducible automation, prefer the exact SemVer tag or, when strict immutability is required, pin the image by digest.

GHCR:

Terminal window
docker pull ghcr.io/rodri-oliveira-dev/adr-guard:latest

Docker Hub:

Terminal window
docker pull rodrigodotnet/adr-guard:latest

Mount the repository at /workspace, which is the image working directory:

Terminal window
docker run --rm \
-v "$PWD:/workspace:ro" \
ghcr.io/rodri-oliveira-dev/adr-guard:latest \
check docs/adr

Validation can use a read-only mount because check does not write repository files.

The reusable GitHub Action applies stricter defaults on top of this image: read-only root filesystem, read-only consumer workspace for check, all Linux capabilities dropped, no-new-privileges, and networking disabled. See the GitHub Action security model.

index writes to the mounted repository. On Linux and macOS, using the host UID/GID avoids ownership mismatches on generated files:

Terminal window
docker run --rm \
--user "$(id -u):$(id -g)" \
-v "$PWD:/workspace" \
ghcr.io/rodri-oliveira-dev/adr-guard:latest \
index docs/adr

The image itself defaults to a non-root user. The explicit --user option above is only for matching ownership on writable host mounts where required.

Offline new and custom templates (available from v1.1.0)

Section titled “Offline new and custom templates (available from v1.1.0)”

Published container images include new and custom-template support starting with v1.1.0. Use a published stable image; no feature-branch build is required. For moving-major consumption use :1, or pin an exact SemVer tag/digest when reproducibility is required:

Terminal window
mkdir -p docs/adr
docker run --rm --user "$(id -u):$(id -g)" \
-v "$PWD:/workspace" ghcr.io/rodri-oliveira-dev/adr-guard:1 \
new docs/adr --title "Adopt Redis" --template minimal --culture en-US
docker run --rm --user "$(id -u):$(id -g)" \
-v "$PWD:/workspace" ghcr.io/rodri-oliveira-dev/adr-guard:1 \
new docs/adr --title "Adopt Cache" \
--template-file docs/examples/templates/team.en-US.md
docker run --rm -v "$PWD:/workspace:ro" \
ghcr.io/rodri-oliveira-dev/adr-guard:1 check docs/adr
docker run --rm --user "$(id -u):$(id -g)" \
-v "$PWD:/workspace" ghcr.io/rodri-oliveira-dev/adr-guard:1 \
index docs/adr

new is offline and secret-free: do not provide OPENAI_API_KEY or other provider credentials. The directory must already exist and be writable by the container user; the template file resolves relative to the container’s /workspace working directory and must be readable. Use a read-only mount for new --preview/--dry-run, which print the proposed Markdown without writing. A real new does not update the index automatically. Earlier v1.0.x images do not include these options.

See offline creation, validated examples and exit codes, custom placeholders and template-based AI draft/privacy. The published GitHub Action @v1 supports check, index, and opt-in review; new and AI-assisted draft remain CLI/direct-container workflows.

Provider credentials must be supplied at runtime through environment variables. They are never baked into the image.

Example with OpenAI:

Terminal window
docker run --rm \
--user "$(id -u):$(id -g)" \
-e OPENAI_API_KEY \
-v "$PWD:/workspace" \
ghcr.io/rodri-oliveira-dev/adr-guard:latest \
draft docs/adr \
--title "Adopt a message broker" \
--context "We need asynchronous integration." \
--provider openai \
--model <openai-model>

The same environment-variable rules documented for the .NET Tool apply to Anthropic, Gemini, and OpenAI-compatible providers.

The container path is protected by multiple independent controls:

  • Hadolint is a required CI gate for the Dockerfile;
  • Dependabot monitors the .NET base images referenced by the Dockerfile;
  • CI builds and smoke-tests the image before a release can run;
  • Trivy scans the built CI image for fixable HIGH and CRITICAL OS/library vulnerabilities and fails the workflow when any are found;
  • the runtime image is based on the .NET chiseled image and runs as a non-root user;
  • release images carry OCI source, documentation, author, license, version, and revision metadata;
  • BuildKit publishes an SBOM attestation and mode=max provenance attestation with each multi-platform release;
  • the release workflow verifies that both linux/amd64 and linux/arm64 manifests and attestation manifests are present in GHCR and Docker Hub.

The SBOM and provenance are OCI attestations associated with the published image index rather than files embedded inside the runtime filesystem.

Inspect the multi-platform manifest and associated attestations:

Terminal window
docker buildx imagetools inspect \
ghcr.io/rodri-oliveira-dev/adr-guard:1.2.3

To use an immutable image reference, resolve the digest and pin it:

ghcr.io/rodri-oliveira-dev/adr-guard@sha256:<digest>

Container images are published only after the CI workflow for the validated main commit succeeds. The release workflow then resolves the same SemVer version used by the NuGet package, creates/verifies the Git tag, publishes the multi-platform image to GHCR and Docker Hub, verifies the published manifests and attestations, and only then completes the GitHub Release.