Best practices

Automate Docker Base Image Updates with Renovate

Published July 31, 2026 · 9 min read

Manually remembering to rebuild against a fresh base image is a patch cadence that fails the moment someone is on vacation. This guide covers how to automate Docker base image updates end to end with Renovate (or Dependabot): the bot proposes the update, a scheduled rebuild runs, and a scan gate decides whether it merges.

Automating Docker base image updates

Why manual base image updates fail

A base image update is easy to defer indefinitely because nothing forces it — the build keeps succeeding against the stale cached layer, and the only signal that patches are available is a scan report someone has to remember to run. Automation replaces “someone remembers” with a process that runs whether or not anyone is watching.

Step 1: Track base image digests with Renovate

Renovate watches your Dockerfiles for FROM lines and opens a pull request when a newer digest is published under the tag you use:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "docker": {
    "enabled": true,
    "pinDigests": true
  },
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "schedule": ["before 6am on monday"]
    }
  ]
}

pinDigests makes Renovate rewrite your FROM line to an explicit digest and then open pull requests when that digest changes, giving you reproducible builds without losing update visibility.

Step 2: Or use Dependabot if you are already on GitHub

Dependabot supports Docker natively with less configuration if Renovate is not already in your stack:

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "docker"
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
    open-pull-requests-limit: 5

Dependabot scans every Dockerfile in the target directory and opens one pull request per base image with an available update, each independently reviewable.

Step 3: Gate the pull request on a rebuild and scan

A bot-opened pull request is only useful if CI proves the new base still builds cleanly and does not introduce new critical findings:

name: base-image-update-check
on:
  pull_request:
    paths: ["Dockerfile"]
jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build --pull -t myapp:pr .
      - run: docker save myapp:pr -o myapp.tar
      - run: curl -fsSL https://scanrook.io/install.sh | sh
      - run: scanrook scan --file myapp.tar --format json --out report.json
      - run: |
          NEW_CRIT=$(jq '.summary.critical' report.json)
          if [ "$NEW_CRIT" -gt 0 ]; then
            echo "::error::$NEW_CRIT critical findings introduced by base image update"
            exit 1
          fi

Require this check to pass before merge in your branch protection rules, so a base image bump that regresses security cannot land silently.

Step 4: Add a scheduled rebuild independent of dependency bots

Renovate and Dependabot only propose an update when the digest actually changes upstream. A separate scheduled job that rebuilds against whatever is current catches OS security patches that land between bot checks:

name: scheduled-rebuild
on:
  schedule:
    - cron: "0 3 * * *" # nightly
jobs:
  rebuild:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build --pull --no-cache -t myapp:nightly .
      - run: docker save myapp:nightly -o myapp.tar
      - run: curl -fsSL https://scanrook.io/install.sh | sh
      - run: scanrook scan --file myapp.tar --format json --out report.json
      - uses: actions/upload-artifact@v4
        with:
          name: nightly-scan-report
          path: report.json

Step 5: Auto-merge only with a passing scan and test suite

Auto-merging removes the last manual step, but only do it when the merge is conditioned on both your test suite and the scan gate from Step 3:

# .github/workflows/automerge.yml
name: automerge-base-image-bumps
on:
  pull_request_target:
    types: [labeled]
jobs:
  automerge:
    if: contains(github.event.pull_request.labels.*.name, 'base-image-bump')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: gh pr merge --auto --squash "$PR_URL"
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PR_URL: ${{ github.event.pull_request.html_url }}

This only fires once required status checks — including the scan gate — are green, so an automated merge still cannot bypass the verification from Step 3.

Verifying the automation is actually working

Check that pull requests are landing on schedule and that the scan gate is doing real work, not silently passing:

# Confirm Renovate/Dependabot PRs are appearing weekly
gh pr list --label "base-image-bump" --state all --limit 10

# Confirm the scan gate has actually failed a build at least once in testing
# by intentionally reverting to an older, known-vulnerable base tag locally
docker build --pull -t myapp:regression-test .
docker save myapp:regression-test -o regression.tar
scanrook scan --file regression.tar --format json --out regression.json
jq '.summary.critical' regression.json

Where ScanRook fits

Automation only closes the loop if the scan gate is trustworthy. ScanRook returns JSON severity totals purpose-built for a CI conditional, so the automerge workflow above has a real signal to check rather than a rubber stamp. Our GitHub Actions scanning guide and the scanner comparison cover the wider CI landscape; see the docs for setup.

Frequently asked questions

How do I automate Docker base image updates?

Use Renovate or Dependabot to open pull requests on digest changes, and gate merges on a rebuild-and-scan CI check.

Does Renovate update by digest or by tag?

Both, depending on config — pinning by digest with Renovate-managed updates gives reproducible builds without losing visibility.

How often should a scheduled rebuild run?

Weekly for most services, nightly for internet-facing ones, balanced against CI capacity.

Should automated updates auto-merge?

Only when gated on a passing scan and test suite — otherwise automation reintroduces the risk it was meant to remove.

Give your automation a real scan gate

ScanRook returns severity totals in JSON, built for a CI conditional, so every automated base image bump has a real pass/fail check.

Related Posts

More on this topic.