Skip to content

Adopt GHCR-mirrored devcontainer base image across all projects #173

@DevSecNinja

Description

@DevSecNinja

Context

mcr.microsoft.com intermittently WAF-blocks GitHub runner egress IPs ("The request is blocked." HTML response with Ref A/B/C), which fails the uncontrollable container-init image pull in CI jobs that use container.image. There is no way to retry or authenticate that pull from within the workflow.

To work around this, DevSecNinja/dotfiles now mirrors the upstream devcontainer base image into GHCR and consumes it from there:

  • Upstream mcr.microsoft.com/devcontainers/base:debian-12 is mirrored to ghcr.io/devsecninja/devcontainers-base:debian-12 by a scheduled matrix workflow (mirror-base-image.yaml), pinned by digest and kept current by Renovate.
  • CI jobs pull the GHCR copy by tag (with credentials: + packages: read). GHCR has no WAF in front of it.

A reusable Renovate custom manager for digest-pinned container images was also added to this repo's shared preset (.renovate/customManagers.json5, #172).

Goal

Audit all projects (public and private) that still reference the upstream image directly and migrate them to the GHCR mirror.

An org-wide search for mcr.microsoft.com/devcontainers/base:debian surfaces several remaining references (not listed here since some live in private repos).

Per-repo migration checklist

For each repo that pulls the base image in a container: job:

  • Replace mcr.microsoft.com/devcontainers/base:debian-12 with ghcr.io/devsecninja/devcontainers-base:debian-12
  • Add a credentials: block (username: ${{ github.actor }}, password: ${{ secrets.GITHUB_TOKEN }}) and permissions: packages: read
  • If the value lives in env, expose it via a job outputs and reference needs.<job>.outputs.*env is not available in jobs.<id>.container.image
  • Ensure the mirror covers the tag(s) the repo needs (add a matrix entry to mirror-base-image.yaml if a new tag/image is required)
  • Confirm CI is green after the change

Reference implementation

See DevSecNinja/dotfiles:

  • .github/workflows/mirror-base-image.yaml (the mirror)
  • .github/workflows/ci.yaml (consuming the mirror; BASE_IMAGE routed through a validate job output)

Notes

  • The mirror is owner-scoped under ghcr.io/devsecninja/. Private repos consuming it need package read access for their GITHUB_TOKEN/actor.
  • Consider promoting the mirror workflow itself into a reusable workflow/template in this repo if more than a couple of projects need it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions