Skip to main content
友田 陽大
Dependabot & dependency automation
Dependabot
Docker
サプライチェーンセキュリティ
DevSecOps
依存関係管理
セキュリティ

Safely update Docker base images with Dependabot: tag following, digest pinning, and silent-rebuild countermeasures

An implementation guide to keep Dockerfile / Docker Compose base images safely updated with Dependabot. Faithful to the official documentation (as of June 2026), it explains, with copy-paste real code: the docker / docker-compose ecosystem configuration, the difference between tag updates and digest pinning (image:tag@sha256:...), countermeasures for CVEs accumulated by silent rebuilds, multi-stage and private-registry (ECR/Artifact Registry) integration, and the reason to be careful with auto-merge.

Published
Reading time
6 min read
Author
友田 陽大
Share

FROM node:22 — this one line brings the whole OS and system libraries into your container. No matter how cleanly you update the app's npm dependencies, if the underlying base image is old, the container's CVEs don't decrease. The base image is actually the biggest dependency.

Dependabot's docker ecosystem auto-follows this base image. This article explains Docker base-image updates at the implementation level, from a reproducibility and security view, as a topic of the Dependabot production-operations guide.

Rules for this article: ecosystem names and behavior are based on the GitHub official documentation and Dependabot's public info (as of June 2026). Docker Compose version updates went GA in February 2025. Always confirm the latest in the official supported ecosystems before production.


0. Why the base image is "the biggest dependency"

あなたのコンテナ = アプリコード
                + アプリ依存(npm/pip/gem …)← 多くの人がここだけ更新する
                + ベースイメージ(OS + システムライブラリ)← 実はここが最大

openssl, glibc, zlib — serious CVEs often appear on the system-library side. Since these are included in the base image, they aren't fixed unless you update the base image. Feeling safe after updating only the app dependencies is a half measure.


1. The basics of the docker ecosystem

Add docker (and docker-compose if needed) to dependabot.yml.

version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/"            # Dockerfile のある場所
    schedule:
      interval: "weekly"
    commit-message:
      prefix: "chore(docker)"

  # docker-compose.yml のイメージも更新(2025年2月にGA)
  - package-ecosystem: "docker-compose"
    directory: "/"
    schedule:
      interval: "weekly"

Dependabot parses the FROM lines of Dockerfile and the image: of Compose, and opens a PR when a new tag comes out. The same mechanism applies to images in Kubernetes manifests and Helm-chart YAML too.


2. Tag updates vs digest pinning

Base-image references have levels of reproducibility.

ReferenceExampleReproducibilityNote
Mutable tagnode:22LowThe contents can change even for the same tag (below)
Version-specified tagnode:22.11.0-bookworm-slimMidMore specific but the tag is mutable
Digest pinnode:22-slim@sha256:abc...HighImmutable. Fixed to the exact image you audited

The form of digest pinning is as follows.

# タグ+digest(再現性が高い)
FROM node:22-slim@sha256:1a2b3c4d...

# Dependabot は digest があれば、タグと digest を同時に更新する

If @sha256:... is attached, Dependabot updates the tag and digest together to the new values (exactly the same philosophy as SHA pinning for GitHub Actions). You can reconcile reproducibility (the same build yields the same result) and update automation.


3. Silent rebuild: why digest pinning works

"I specify node:22, so it's always the same" — this is wrong. A silent rebuild (the upstream maintainer swapping the image's contents while keeping the same tag) happens routinely. A rebuild to apply security patches is good, but if you only look at the tag, you can't tell when the contents changed.

Here digest pinning works.

  • Pinning the digest means that even if the upstream swaps contents under the same tag, your build keeps using the fixed image (reproducibility).
  • Running Dependabot daily brings a digest-update PR when the upstream issues a new digest. So "when and what changed" is visualized as a PR and taken in after review.
  • As a result, you can structurally reduce image CVE rot (vulnerabilities accumulated by neglect).
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "daily"        # digest 追従は日次が効く
    commit-message:
      prefix: "chore(docker)"

"Fixing for reproducibility" and "updating for freshness" aren't contradictory. Fix (digest pin) and update via PR (Dependabot) — this combination is the norm that satisfies reproducibility and security simultaneously.


4. Multi-stage and minimal images

A practical Dockerfile is multi-stage. Dependabot targets the FROM of each stage for updates.

# ---- build stage ----
FROM node:22-slim@sha256:aaa... AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ---- runtime stage(最小・非root) ----
FROM gcr.io/distroless/nodejs22-debian12@sha256:bbb... AS runner
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER nonroot
CMD ["dist/server.js"]

Design points (cost efficiency and security):

  • Choosing a minimal image like distroless / -slim / alpine shrinks the attack surface, the number of CVEs, and the image size (= registry/transfer cost).
  • Digest-pin both stages and have Dependabot follow them.
  • Run non-root (USER nonroot) to minimize runtime privileges.

5. Private-registry base images

You can update base images in an internal ECR / Artifact Registry / Artifactory too. Define docker-registry authentication in registries.

version: 2
registries:
  ecr:
    type: docker-registry
    url: 111122223333.dkr.ecr.ap-northeast-1.amazonaws.com
    username: ${{secrets.DEPENDABOT_AWS_ACCESS_KEY_ID}}
    password: ${{secrets.DEPENDABOT_AWS_SECRET_ACCESS_KEY}}
updates:
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
    registries: ["ecr"]

ECR uses static AWS credentials; Artifact Registry / Artifactory can also use OIDC. For per-type authentication details and self-hosted runners, head to the private-registry authentication guide.


6. Auto-merge "carefully"

A base-image update is a change to the OS and system libraries. Since the impact is harder to read than an app-dependency patch, be one notch more careful with auto-merge.

  • patch / within-same-major updates (e.g. 22.11.022.11.1, digest following) are auto-merge candidates if the build + smoke test passes.
  • Major updates (e.g. debian 12 → 13, node 22 → 24) require human review since glibc or system-library incompatibilities can occur.
  • Pair with image scanning: Dependabot mainly does GitHub-Advisory-based dependency updates. To directly see vulnerabilities in the container's packages, add Trivy / Grype image scanning to CI, and on a digest-update PR confirm whether the scan result worsened (how to choose an SCA tool).
      - name: Auto-merge docker patch / digest bumps
        if: |
          steps.meta.outputs.package-ecosystem == 'docker' &&
          steps.meta.outputs.update-type == 'version-update:semver-patch'
        run: gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

For the auto-merge token model and the safety valve (required checks), see the auto-merge guide.


7. Checklist

  • Add package-ecosystem: docker (and docker-compose if needed)
  • Digest-pin the base image with tag@sha256:... (reproducibility)
  • Follow the digest with a daily schedule as a silent-rebuild countermeasure
  • A minimal runtime of distroless / slim / non-root in multi-stage
  • Private images with docker-registry auth (ECR = static AWS / Artifact Registry = OIDC)
  • Limit auto-merge to patch / digest following, human review for major
  • Add Trivy / Grype image scanning to CI, with dependency updates and vulnerability detection as both wheels

8. FAQ

Q. Does Dependabot update even with FROM node:22 as-is? A. It can follow tag updates, but reproducibility is low and you can't notice silent rebuilds. Digest-pin with tag@sha256:... and Dependabot updates the tag and digest together, reconciling reproducibility and freshness.

Q. Doesn't digest pinning stop updates? A. It doesn't. Dependabot opens a PR updating to the new digest/tag. A daily schedule follows silent rebuilds too.

Q. Can Docker Compose images be updated too? A. They can. The docker-compose ecosystem went GA in February 2025. Use it alongside Dockerfile.

Q. May I auto-merge base images? A. Limit it to patch / digest following, and route OS major updates to human review. Incompatibilities like glibc can occur.

Q. Is Dependabot alone enough for container security? A. Dependabot mainly does dependency (GitHub Advisory) updates. For comprehensive scanning of the container's packages, pair it with Trivy/Grype. The role division is explained in the SCA-tool comparison.

友田

友田 陽大

Developer of a METI Minister's Award–winning product. With TypeScript + Python + AWS, I deliver SaaS, industry DX, and production-grade generative AI (RAG) end to end — from requirements to infrastructure and operations — single-handedly.

I can take on the implementation from this article as an engagement

Dependency auto-updates & supply-chain defense, from design to production

From enabling alerts/security/version updates, to dependabot.yml design (groups, cooldown, monorepo directories, private registries), safe auto-merge via GitHub Actions + fetch-metadata (auto for patch/minor, human review for major), severity-based-SLA vulnerability response, and observability of the open count. With experience wiring dependency updates into CI quality gates, I implement automation that doesn't flood you with PRs or pile up technical debt.

Available for both project-based (contract) and advisory engagements. Start with a free 30-minute consult.

Also worth reading