Chapter 74: DevOps Projects Part 4: Docker Scan, Network, Logging and Swarm
74.1 Project 27: Scan images with Trivy and fix the findings
Friends, shipping unscanned images is how CVEs reach production. Today we scan a practice image with Trivy, read CRITICAL counts, bump the base image, rescan, and set a CI exit-code gate.
मित्रांनो, unscanned images CVEs production पर्यंत नेतात. आज Trivy ने scan, CRITICAL मोजा, base bump, rescan, CI exit-code gate.
दोस्तों, unscanned images CVEs को production तक ले जाती हैं. आज Trivy से scan, CRITICAL गिनें, base bump, rescan, CI exit-code gate.
What you will build in this project
- Trivy image scan on scanme.
- CRITICAL gate with --exit-code 1.
- Base bump and rescan.
- fs/config scan and JSON report tips.
1. Start from a real company story
At Razorpay in Bengaluru, a payment worker image shipped with a CRITICAL openssl CVE for eleven days.
A customer questionnaire failed. Rough cost: about ₹18 lakh in delayed enterprise deals.
Kabir added Trivy with fail-on-CRITICAL in every image job.
Today we practice that scan and fix loop.
Ravindra Bagale's Tip
Many students add a huge .trivyignore to silence the gate. Every ignore needs a ticket and an owner. Keep that habit.
खूप students मोठे .trivyignore टाकून gate शांत करतात. प्रत्येक ignore ला ticket आणि owner हवा. सवय ठेवा.
बहुत students बड़ा .trivyignore डाल gate शांत करते हैं. हर ignore पर ticket और owner चाहिए. आदत रखिए.
2. Start and prepare
Step 1: Install or pull Trivy
Why: Scanner must be on PATH or in a container. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: trivy --version or docker run aquasec/trivy. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 1: ver shape
Type this:
echo 'trivy --version || docker run --rm aquasec/trivy:0.54.1 --version'
You will see:
trivy --version || docker run --rm aquasec/trivy:0.54.1 --version
What it means: Install shape.
Example 2: alias
Type this:
echo 'alias trivy="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.54.1"'
You will see:
alias trivy="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.54.1"
What it means: Container alias.
Example 3: why pin
Type this:
echo 'Pin the Trivy tag so CI does not drift'
You will see:
Pin the Trivy tag so CI does not drift
What it means: Habit.
Step 2: Build sample image
Why: Need an image to scan. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: docker build. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 4: df
Type this:
mkdir -p /tmp/trivy-lab && printf '%s\n' 'FROM python:3.9-slim' 'WORKDIR /app' 'COPY app.py .' 'CMD ["python","app.py"]' > /tmp/trivy-lab/Dockerfile && printf '%s\n' 'print("ok")' > /tmp/trivy-lab/app.py && docker build -t scanme:1.0 /tmp/trivy-lab
You will see:
Successfully tagged scanme:1.0
What it means: Built.
Example 5: images
Type this:
docker images scanme:1.0 --format '{{.Repository}}:{{.Tag}}'
You will see:
scanme:1.0
What it means: Listed.
Example 6: why old
Type this:
echo '3.9-slim may carry known CVEs; that is intentional for the lab'
You will see:
3.9-slim may carry known CVEs; that is intentional for the lab
What it means: Setup.
Step 3: trivy image scan
Why: trivy image finds CVEs. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: trivy image --severity. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 7: scan shape
Type this:
echo 'trivy image --severity HIGH,CRITICAL scanme:1.0'
You will see:
trivy image --severity HIGH,CRITICAL scanme:1.0
What it means: Scan cmd.
Example 8: docker form
Type this:
echo 'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.54.1 image --severity HIGH,CRITICAL scanme:1.0'
You will see:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:0.54.1 image --severity HIGH,CRITICAL scanme:1.0
What it means: Via container.
Example 9: first run
Type this:
echo 'First run downloads the vulnerability DB; later runs are faster'
You will see:
First run downloads the vulnerability DB; later runs are faster
What it means: DB.
3. Build the main pieces
Step 4: Read CRITICAL count
Why: Counts drive the gate. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: Count CRITICAL. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 10: count tip
Type this:
echo 'Read the summary line: CRITICAL: N HIGH: M'
You will see:
Read the summary line: CRITICAL: N HIGH: M
What it means: Summary.
Example 11: gate
Type this:
echo 'Exit code 1 when findings match --exit-code 1'
You will see:
Exit code 1 when findings match --exit-code 1
What it means: Gate.
Example 12: cmd
Type this:
echo 'trivy image --exit-code 1 --severity CRITICAL scanme:1.0'
You will see:
trivy image --exit-code 1 --severity CRITICAL scanme:1.0
What it means: Fail on CRITICAL.
Step 5: Fix base tag
Why: Old bases are the usual fix. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: Bump FROM pin. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 13: fix
Type this:
printf '%s\n' 'FROM python:3.12-alpine' 'WORKDIR /app' 'COPY app.py .' 'CMD ["python","app.py"]' > /tmp/trivy-lab/Dockerfile && docker build -t scanme:1.1 /tmp/trivy-lab
You will see:
Successfully tagged scanme:1.1
What it means: Newer base.
Example 14: diff
Type this:
docker images 'scanme' --format '{{.Tag}} {{.Size}}'
You will see:
1.0 ...
1.1 ...
What it means: Two tags.
Example 15: why alpine
Type this:
echo 'Alpine + newer Python usually cuts OS CVEs'
You will see:
Alpine + newer Python usually cuts OS CVEs
What it means: Reason.
Step 6: Rescan after fix
Why: Rescan proves the fix. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: trivy again. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 16: rescan
Type this:
echo 'trivy image --severity HIGH,CRITICAL scanme:1.1'
You will see:
trivy image --severity HIGH,CRITICAL scanme:1.1
What it means: Rescan.
Example 17: compare
Type this:
echo 'Compare CRITICAL count 1.0 vs 1.1 before you merge'
You will see:
Compare CRITICAL count 1.0 vs 1.1 before you merge
What it means: PR habit.
Example 18: tag prod
Type this:
echo 'Only promote the tag that passed the gate'
You will see:
Only promote the tag that passed the gate
What it means: Promote.
4. Automate and verify
Step 7: Ignore file tip
Why: Some findings are accepted with reason. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: .trivyignore. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 19: ignore
Type this:
printf '%s\n' '# Accepted until vendor patch; ticket SEC-441' 'CVE-2024-EXAMPLE' > /tmp/trivy-lab/.trivyignore && cat /tmp/trivy-lab/.trivyignore
You will see:
# Accepted...
CVE-2024-EXAMPLE
What it means: Ignore file.
Example 20: use
Type this:
echo 'trivy image --ignorefile /tmp/trivy-lab/.trivyignore scanme:1.1'
You will see:
trivy image --ignorefile /tmp/trivy-lab/.trivyignore scanme:1.1
What it means: Flag.
Example 21: rule
Type this:
echo 'Every ignore line needs a ticket id and an expiry note'
You will see:
Every ignore line needs a ticket id and an expiry note
What it means: Policy.
Step 8: CI gate tip
Why: CI must fail on CRITICAL. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: exit code in CI. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 22: ci
Type this:
echo 'In CI: trivy image --exit-code 1 --severity CRITICAL $IMAGE'
You will see:
In CI: trivy image --exit-code 1 --severity CRITICAL $IMAGE
What it means: CI line.
Example 23: fail
Type this:
echo 'Pipeline fails closed when CRITICAL remains'
You will see:
Pipeline fails closed when CRITICAL remains
What it means: Fail closed.
Example 24: who
Type this:
echo 'Security and app owners jointly accept ignores'
You will see:
Security and app owners jointly accept ignores
What it means: Owners.
Step 9: Scan filesystem
Why: fs scan catches lockfiles. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: trivy fs. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 25: fs
Type this:
echo 'trivy fs --severity HIGH,CRITICAL /tmp/trivy-lab'
You will see:
trivy fs --severity HIGH,CRITICAL /tmp/trivy-lab
What it means: Lockfiles.
Example 26: why fs
Type this:
echo 'fs scan catches package.json and requirements before image build'
You will see:
fs scan catches package.json and requirements before image build
What it means: Early.
Example 27: lock
Type this:
echo 'Commit lockfiles so scans are repeatable'
You will see:
Commit lockfiles so scans are repeatable
What it means: Locks.
5. Harden and accept
Step 10: Scan config
Why: config scan catches bad Dockerfiles. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: trivy config. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 28: config
Type this:
echo 'trivy config /tmp/trivy-lab'
You will see:
trivy config /tmp/trivy-lab
What it means: Dockerfile rules.
Example 29: findings
Type this:
echo 'Looks for root user, latest tags, secrets in ENV'
You will see:
Looks for root user, latest tags, secrets in ENV
What it means: What.
Example 30: fix tip
Type this:
echo 'Fix config findings in the same PR as the image bump'
You will see:
Fix config findings in the same PR as the image bump
What it means: PR.
Step 11: Save report JSON
Why: JSON feeds dashboards. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: -f json -o. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 31: json
Type this:
echo 'trivy image -f json -o /tmp/scanme.json scanme:1.1'
You will see:
trivy image -f json -o /tmp/scanme.json scanme:1.1
What it means: JSON.
Example 32: table
Type this:
echo 'trivy image -f table scanme:1.1'
You will see:
trivy image -f table scanme:1.1
What it means: Human.
Example 33: store
Type this:
echo 'Archive JSON next to the build artifact for audits'
You will see:
Archive JSON next to the build artifact for audits
What it means: Audit.
Step 12: Acceptance checklist
Why: Kabir signs off when CRITICAL is zero or accepted. We do this before the next step so mistakes stay small and easy to undo. Read the output carefully; the numbers and names tell you if the scan or network is healthy today.
What: All green. Follow the numbered examples below. Type each command, read the exact output, and match the meaning line before you move on. That is how real teams harden containers.
Example 34: critical zero
Type this:
echo 'Goal: CRITICAL=0 or listed in .trivyignore with ticket'
You will see:
Goal: CRITICAL=0 or listed in .trivyignore with ticket
What it means: Goal.
Example 35: tag
Type this:
echo scanme:1.1
You will see:
scanme:1.1
What it means: Promote.
Example 36: Sign-off
Type this:
echo 'Kabir: PASS'
You will see:
Kabir: PASS
What it means: Done.
Check yourself
Q1. Who gated Razorpay images?
Kabir
Q2. Scanner name?
Trivy
Q3. Fail flag?
--exit-code 1
Q4. Ignore file?
.trivyignore
Q5. Old base in lab?
python:3.9-slim
Q6. Fixed base?
python:3.12-alpine
Friends, you scanned, fixed and gated an image with Trivy. Did you understand? Let us try it once more. Wire the same --exit-code 1 line into your Jenkins or Actions job next.
मित्रांनो, तुम्ही Trivy ने scan-fix-gate केले. पुढे तोच --exit-code 1 Jenkins किंवा Actions मध्ये जोडा.
दोस्तों, आपने Trivy से scan-fix-gate किया. आगे वही --exit-code 1 Jenkins या Actions में जोड़ें.
Lab: try at home
- Build scanme:1.0 on an older base.
- Scan with HIGH,CRITICAL.
- Rebuild on alpine 3.12.
- Rescan and compare.
- Add CI exit-code gate.
Recap
- Pin Trivy version.
- CRITICAL drives the gate.
- Ignore needs a ticket.
- fs scan catches lockfiles early.
- Archive JSON for audits.