Quick Start
This guide walks you through patching container vulnerabilities using Copa. You'll learn how to scan an image for vulnerabilities, apply security patches, and verify the results.
What You'll Learn
- How to scan container images for OS-level vulnerabilities
- Two patching strategies: comprehensive vs. targeted patching
- How to verify successful patching and test patched images
Prerequisites
Before you begin, ensure you have:
- Copa CLI - Follow the installation guide to build and install Copa
- Container Runtime - Copa supports both Docker and Podman:
- Docker - Docker running with CLI installed (installation guide)
- Podman - Podman running with CLI installed (installation guide)
- BuildKit instance - Copa auto-detects available instances in this order:
- Docker's built-in BuildKit (requires Docker v24.0+ with containerd image store enabled for local images)
- Current buildx builder (create one with
docker buildx create --use) - BuildKit daemon at
/run/buildkit/buildkitd.sock(see custom addresses for examples)
- Trivy CLI (optional) - For vulnerability scanning (installation guide)
For advanced BuildKit configurations, see custom BuildKit addresses.
Tutorial
This tutorial demonstrates patching the nginx:1.21.6 image, which contains numerous vulnerabilities.
This tutorial shows Docker commands, but Copa works with both Docker and Podman. Where Docker commands are shown, you can substitute podman for docker in most cases.
Step 1: Set up the Environment
First, set the image we'll be working with:
export IMAGE=docker.io/library/nginx:1.21.6
If you want to patch an image using the digest, you can specify the digest like this:
export IMAGE=docker.io/library/nginx@sha256:25dedae0aceb6b4fe5837a0acbacc6580453717f126a095aa05a3c6fcea14dd4
Copa automatically detects and connects to an available BuildKit instance. If you need a specific instance, see custom BuildKit addresses.
Step 2: Scan for Vulnerabilities
Scan the image to identify OS-level vulnerabilities:
trivy image --vuln-type os --ignore-unfixed $IMAGE
Expected output:
nginx:1.21.6 (debian 11.3)
==========================
Total: 207 (UNKNOWN: 0, LOW: 12, MEDIUM: 104, HIGH: 76, CRITICAL: 15)
Step 3: Choose Your Patching Strategy
Copa offers two patching approaches:
Option A: Comprehensive Patching
Update all outdated packages to their latest versions:
copa patch -i $IMAGE
This approach provides the most comprehensive security updates but may introduce compatibility issues. Always test patched images thoroughly before production use.
Option B: Targeted Patching
Update only packages with known vulnerabilities:
-
Generate a vulnerability report:
trivy image --vuln-type os --ignore-unfixed -f json -o nginx-report.json $IMAGE -
Patch using the vulnerability report:
copa patch -r nginx-report.json -i $IMAGE
Apt-less images with /var/lib/dpkg/status support both strategies. Native
images with /var/lib/chisel/manifest.wall support comprehensive patching only
and reject --report. See Ubuntu Chiseled Images before
patching either layout.
Both methods create a new image tagged nginx:1.21.6-patched in your local registry.
For local exports, Copa stores newly created patch layers with --compression=uncompressed by default so scanners can read the patched image reliably. Existing base layers are preserved in their original compression unless you use --force-compression to re-encode layers exported for patched platforms to the selected compression. Platforms preserved unchanged in a multi-platform OCI layout keep their original layer blobs and compression.
The image used in this tutorial is a multi-platform image containing many different platforms. To learn more about multi-platform patching, see multi-platform patching docs.
Step 4: Verify the Patch
Scan the patched image to confirm vulnerabilities were resolved:
trivy image --vuln-type os --ignore-unfixed $IMAGE-patched
Expected output:
nginx:1.21.6-patched (debian 11.10)
===================================
Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0)
This Trivy verification works for apt-less Chiseled images that retain
/var/lib/dpkg/status. For native images that contain
/var/lib/chisel/manifest.wall, a zero-package or zero-vulnerability Trivy
result is not evidence that the image is current. Copa validates the replacement
manifest and managed filesystem; also run the patched application's normal
startup or smoke test before deployment.
Step 5: Test the Patched Image
Verify the patched image works correctly:
docker run -d --name test-nginx -p 8080:80 $IMAGE-patched
Test that nginx is responding:
curl -I http://localhost:8080
Expected output:
HTTP/1.1 200 OK
Server: nginx/1.21.6
Clean up:
docker stop test-nginx && docker rm test-nginx
Step 6: Inspect the Changes (Optional)
View the patch layer added by Copa:
# Using Docker
docker history $IMAGE-patched --format "table {{.ID}}\t{{.CreatedSince}}\t{{.Size}}\t{{.Comment}}"
The first entry shows the patch layer with security updates.
Summary
You've successfully:
- ✅ Scanned a container image for vulnerabilities
- ✅ Applied security patches using Copa
- ✅ Reviewed scanner results and tested the patched application
- ✅ Learned about different patching strategies
The selected fixable package updates have been applied to
nginx:1.21.6-patched. Review the scanner results appropriate to the image
layout and complete application testing before deployment.
Next Steps
- Learn about scanner plugins for custom vulnerability sources
- Explore custom BuildKit configurations
- Read best practices for production use
- Check out the Copa Action for GitHub Action integration
- Check out the Docker Extension for GUI-based patching