Patch Docker Image
ActionsTags
(2)Docker image vulnerability patching for Node.js and Python container images.
This tool provides:
- A CLI tool (
docker-vuln-patcher) for local and CI/CD usage - A public reusable GitHub Action (
qasimnauman/patch-docker-image@v1) - Verification gating that fails the run if targeted fixable CVEs still remain
Supported modes only:
- Public GitHub Action consumption via
qasimnauman/patch-docker-image@v1 - CLI usage via
docker-vuln-patcher(orpatch_image.py)
Most patch automation flows stop at "build succeeded". This project enforces a stronger rule:
- Scan
- Patch
- Re-scan
- Fail unless targeted fixable vulnerabilities are actually reduced to zero for selected severities
This prevents false-success pipelines and gives safer production outcomes.
Supported runtime families:
- Node.js images
- Python images
Supported patch surfaces:
- OS packages when available (
apt,apk,yum,dnf) npmpip
Current non-goals:
- Runtime families outside Node.js/Python
- Guaranteed remediation for every base image/CVE combination
- Resolve inputs (image, Dockerfile path, credentials, options)
- Build source image from Dockerfile or pull source image from registry
- Run baseline Docker Scout scan
- Select fixable CVEs by severity
- Generate patch Dockerfile and patch plan artifacts
- Build patched image
- Run post-patch Docker Scout verification
- Fail if targeted fixable CVEs remain
- Optionally push verified patched image
Input precedence and source:
| Input | Source | Resolution behavior |
|---|---|---|
| Image | --image (required) |
Always required target reference |
| Dockerfile | --dockerfile-path |
If provided, build source image first |
| Build context | --context-path |
If omitted, defaults to Dockerfile parent |
| Build args | repeated --build-arg KEY=VALUE |
Passed to source image build |
| Docker Hub username | --dh-user then env from --dh-user-env |
--dh-user has priority |
| Docker Hub password/token | env from --dh-password-env |
Used with docker login --password-stdin |
| Non-interactive mode | --non-interactive |
Fails when required credentials are missing |
| Report output folder | --report-dir |
Defaults to ./vuln_reports |
Image source behavior:
- If
--dockerfile-pathis set: build source image from local files. - If
--dockerfile-pathis not set: pull--imagefrom registry.
Action input sources:
- Image/build inputs come from
with:values in workflow YAML. - Credentials are typically wired from repository/org secrets.
Recommended secret mapping:
dh-user: ${{ secrets.DOCKERHUB_USERNAME }}dh-password: ${{ secrets.DOCKERHUB_PASSWORD }}
Dockerfile behavior is identical to CLI:
dockerfile-pathset -> build first from workflow workspace.dockerfile-pathempty -> pullimagefrom registry.
name: Patch Docker Image
on:
workflow_dispatch:
jobs:
patch:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Patch and verify image
id: patch
uses: qasimnauman/patch-docker-image@v1
with:
image: myrepo/myapp:latest
severities: CRITICAL,HIGH,MEDIUM,LOW
push: "false"
non-interactive: "true"
dh-user: ${{ secrets.DOCKERHUB_USERNAME }}
dh-password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Output patched tag
run: echo "Patched image: ${{ steps.patch.outputs.patched_image }}"Install:
python -m pip install --upgrade pip
pip install .Patch an existing registry image:
docker-vuln-patcher \
--image myrepo/myapp:latest \
--non-interactive \
--report-dir ./vuln_reportsBuild from Dockerfile, then patch:
docker-vuln-patcher \
--image myrepo/myapp:latest \
--dockerfile-path ./Dockerfile \
--context-path . \
--build-arg APP_ENV=prod \
--non-interactive \
--report-dir ./vuln_reportsPatch, verify, and push:
docker-vuln-patcher \
--image myrepo/myapp:latest \
--non-interactive \
--push| Flag | Required | Default | Description |
|---|---|---|---|
--image |
Yes | none | Target image reference |
--dockerfile-path |
No | none | Build source image from Dockerfile |
--context-path |
No | Dockerfile parent | Build context for Dockerfile mode |
--build-arg |
No | none | Repeatable source-image build args |
--patched-suffix |
No | -patched |
Suffix appended to target image tag |
--severities |
No | CRITICAL,HIGH,MEDIUM,LOW |
Target severities for selection/verification |
--dh-user |
No | none | Docker Hub username override |
--dh-user-env |
No | DOCKERHUB_USERNAME |
Username env var key |
--dh-password-env |
No | DOCKERHUB_PASSWORD |
Password/token env var key |
--non-interactive |
No | false | Disable credential prompt fallback |
--push |
No | false | Push verified patched image |
--use-buildx |
No | false | Build patched image with docker buildx |
--dry-run |
No | false | Skip build/verify/push, generate artifacts only |
--report-dir |
No | ./vuln_reports |
Output folder for artifacts |
--debug |
No | false | Enable debug logs |
Public action:
qasimnauman/patch-docker-image@v1
Primary action file:
- repository root
action.yml
Supported usage policy:
- Use only
qasimnauman/patch-docker-image@v1in workflows.
image(required, default: none): Target image reference.dockerfile-path(optional, default: empty): Optional Dockerfile path.context-path(optional, default: empty): Optional Docker build context.build-args(optional, default: empty): Newline-separatedKEY=VALUEbuild args.severities(optional, default:CRITICAL,HIGH,MEDIUM,LOW): Severity selection.patched-suffix(optional, default:-patched): Patched image suffix.report-dir(optional, default:./vuln_reports): Artifact output folder.dh-user(optional, default: empty): Docker Hub username.dh-password(optional, default: empty): Docker Hub password/token.push(optional, default:false): Push verified patched image.dry-run(optional, default:false): Generate only, skip build/verify/push.non-interactive(optional, default:true): Fail if credentials are missing.use-buildx(optional, default:false): Use buildx for patched build.python-version(optional, default:3.12): Python runtime for action job.
| Output | Description |
|---|---|
patched_image |
Derived patched image tag |
Security behavior:
- Password/token is passed through stdin (
docker login --password-stdin). - Password value is not logged by the tool.
- Credential variables are configurable by key (
--dh-user-env,--dh-password-env).
Best practices:
- Use short-lived tokens instead of account passwords when possible.
- Keep push permissions minimal and scoped.
- Do not commit raw vulnerability reports to public repos without review.
- Treat generated reports as potentially sensitive operational artifacts.
Default output root:
./vuln_reports
Generated artifacts:
- Baseline scan report:
scout_<safe-image>.json - Patch plan:
patch_plan_<safe-image>.json - Post-patch scan report:
post_patch_scout_<safe-image>.json - Generated Dockerfile:
patches/Dockerfile.<safe-image>.patched
0: Success (or nothing fixable for selected severities).1: Invalid configuration/input/auth/runtime error.2: Safe failure (unsupported runtime, no patchable CVEs, or verification failed).
- Pin action usage to a stable major tag (
@v1) or commit SHA. - Configure repository/org secrets for Docker Hub credentials.
- Start with
dry-run: "true"on new repos to validate behavior. - Enable push only after successful verification behavior is confirmed.
- Keep base images and dependency lockfiles updated regularly.
- Monitor release notes and move tags intentionally.
- Ensure Docker is installed and daemon is running on the runner/host.
- Ensure Docker Scout plugin is installed and accessible (
docker scout version).
- This is expected in some image/CVE combinations.
- The tool is intentionally strict and fails to avoid false success.
- Review generated reports and patch Dockerfile under
report-dir.
- Provide
dh-useranddh-passwordfrom secrets. - Keep
non-interactiveenabled for deterministic CI behavior.
- EULA:
EULA.md - Privacy Policy:
PRIVACY.md - Support Policy:
SUPPORT.md - Security Policy:
SECURITY.md
MIT
Resources
Patch Docker Image is not certified by GitHub. It is provided by a third-party and is governed by separate terms of service, privacy policy, and support documentation.