Set up automated container image security scanning using Trivy with Podman to detect vulnerabilities, misconfigurations, and security issues before deploying containers to production.
Prerequisites
- Root or sudo access
- Internet connectivity for downloading vulnerability databases
- At least 2GB free disk space
- Basic knowledge of containers and JSON
What this solves
Container images often contain vulnerabilities in base operating systems, libraries, and dependencies that attackers can exploit. Trivy security scanner integrates with Podman to automatically detect CVEs, secrets, misconfigurations, and license issues in your container images before deployment. This tutorial shows you how to set up automated scanning workflows that catch security problems early in your development pipeline.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you have the latest security updates.
sudo apt update && sudo apt upgrade -y
Install Podman
Install Podman container engine if not already present on your system.
sudo apt install -y podman
Install Trivy security scanner
Download and install the latest version of Trivy from the official repository.
sudo apt update
sudo apt install -y wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt update
sudo apt install -y trivy
Configure Trivy database location
Set up Trivy database directory with proper permissions for vulnerability database updates.
sudo mkdir -p /var/lib/trivy
sudo chown $USER:$USER /var/lib/trivy
export TRIVY_CACHE_DIR=/var/lib/trivy
Update Trivy vulnerability database
Download the latest vulnerability database which contains CVE information for scanning.
trivy image --download-db-only
Configure Podman with Trivy integration
Create scanning configuration file
Set up Trivy configuration file with security scanning policies and output formats.
cache:
dir: /var/lib/trivy
db:
skip-update: false
download-timeout: 10m
vulnerability:
type:
- os
- library
scanners:
- vuln
- secret
- config
severity:
- UNKNOWN
- LOW
- MEDIUM
- HIGH
- CRITICAL
format: table
output: /var/log/trivy-scan.log
ignore-unfixed: false
timeout: 5m
Create log directory with proper permissions
Set up logging directory where Trivy will store scan results and reports.
sudo mkdir -p /var/log/trivy
sudo chown $USER:$USER /var/log/trivy
sudo chmod 755 /var/log/trivy
Create scanning wrapper script
Build an automation script that integrates Trivy scanning with Podman image operations.
#!/bin/bash
Podman + Trivy security scanning wrapper
set -e
Configuration
TRIVY_CONFIG="/etc/trivy/trivy.yaml"
LOG_DIR="/var/log/trivy"
DATE=$(date +%Y%m%d_%H%M%S)
Function to scan image
scan_image() {
local image="$1"
local output_file="${LOG_DIR}/scan_${DATE}_$(echo "$image" | tr '/:' '_').json"
echo "Scanning image: $image"
echo "Output file: $output_file"
# Run Trivy scan
trivy image \
--config "$TRIVY_CONFIG" \
--format json \
--output "$output_file" \
--severity HIGH,CRITICAL \
"$image"
# Check for critical vulnerabilities
critical_count=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
high_count=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
echo "Critical vulnerabilities: $critical_count"
echo "High vulnerabilities: $high_count"
# Generate summary report
trivy image \
--config "$TRIVY_CONFIG" \
--format table \
--severity HIGH,CRITICAL \
"$image"
# Return exit code based on findings
if [ "$critical_count" -gt 0 ]; then
echo "ERROR: Critical vulnerabilities found in $image"
return 1
elif [ "$high_count" -gt 5 ]; then
echo "WARNING: More than 5 high-severity vulnerabilities found in $image"
return 2
fi
echo "Image $image passed security scan"
return 0
}
Function to pull and scan
pull_and_scan() {
local image="$1"
echo "Pulling image: $image"
podman pull "$image"
echo "Scanning pulled image..."
scan_image "$image"
}
Main execution
case "$1" in
scan)
if [ -z "$2" ]; then
echo "Usage: $0 scan "
exit 1
fi
scan_image "$2"
;;
pull-scan)
if [ -z "$2" ]; then
echo "Usage: $0 pull-scan "
exit 1
fi
pull_and_scan "$2"
;;
*)
echo "Usage: $0 {scan|pull-scan} "
echo " scan - Scan existing local image"
echo " pull-scan - Pull image from registry and scan"
exit 1
;;
esac
Make scanning script executable
Set proper permissions on the scanning wrapper script.
sudo chmod 755 /usr/local/bin/podman-scan
sudo chown root:root /usr/local/bin/podman-scan
Install jq for JSON parsing
Install jq utility for parsing Trivy JSON output in the scanning script.
sudo apt install -y jq
Implement automated vulnerability scanning workflows
Create systemd timer for database updates
Set up automatic vulnerability database updates to ensure current CVE data.
[Unit]
Description=Update Trivy vulnerability database
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/bin/trivy image --download-db-only
Environment=TRIVY_CACHE_DIR=/var/lib/trivy
[Install]
WantedBy=multi-user.target
Create systemd timer configuration
Schedule daily vulnerability database updates during low-traffic hours.
[Unit]
Description=Update Trivy database daily
Requires=trivy-db-update.service
[Timer]
OnCalendar=daily
RandomizedDelaySec=3600
Persistent=true
[Install]
WantedBy=timers.target
Enable and start the update timer
Activate the systemd timer for automatic vulnerability database updates.
sudo systemctl daemon-reload
sudo systemctl enable trivy-db-update.timer
sudo systemctl start trivy-db-update.timer
sudo systemctl status trivy-db-update.timer
Create CI/CD integration script
Build a script for integrating security scanning into continuous integration pipelines.
#!/bin/bash
CI/CD security scanning integration
set -e
Configuration
FAIL_ON_CRITICAL=${FAIL_ON_CRITICAL:-true}
FAIL_ON_HIGH=${FAIL_ON_HIGH:-false}
MAX_HIGH_VULNS=${MAX_HIGH_VULNS:-10}
SCAN_TIMEOUT=${SCAN_TIMEOUT:-300}
OUTPUT_FORMAT=${OUTPUT_FORMAT:-json}
Function to scan and evaluate
ci_scan() {
local image="$1"
local build_id="${2:-$(date +%s)}"
local output_file="/tmp/trivy-ci-${build_id}.json"
echo "=== Security Scan Report ==="
echo "Image: $image"
echo "Build ID: $build_id"
echo "Timestamp: $(date)"
echo "=============================="
# Run security scan
timeout "$SCAN_TIMEOUT" trivy image \
--format json \
--output "$output_file" \
--severity HIGH,CRITICAL \
--no-progress \
"$image" || {
echo "ERROR: Scan failed or timed out"
exit 1
}
# Parse results
if [ -f "$output_file" ]; then
critical_vulns=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
high_vulns=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
echo "Critical vulnerabilities: $critical_vulns"
echo "High vulnerabilities: $high_vulns"
# Display summary table
trivy image \
--format table \
--severity HIGH,CRITICAL \
--no-progress \
"$image"
# Apply CI/CD policies
exit_code=0
if [ "$FAIL_ON_CRITICAL" = "true" ] && [ "$critical_vulns" -gt 0 ]; then
echo "❌ FAIL: Critical vulnerabilities found (Policy: FAIL_ON_CRITICAL=true)"
exit_code=1
fi
if [ "$FAIL_ON_HIGH" = "true" ] && [ "$high_vulns" -gt "$MAX_HIGH_VULNS" ]; then
echo "❌ FAIL: Too many high-severity vulnerabilities ($high_vulns > $MAX_HIGH_VULNS)"
exit_code=1
fi
if [ $exit_code -eq 0 ]; then
echo "✅ PASS: Security scan completed successfully"
fi
# Copy results to permanent location if specified
if [ -n "$SCAN_RESULTS_DIR" ]; then
mkdir -p "$SCAN_RESULTS_DIR"
cp "$output_file" "$SCAN_RESULTS_DIR/scan-${build_id}.json"
fi
# Cleanup
rm -f "$output_file"
return $exit_code
else
echo "ERROR: Scan output file not found"
return 1
fi
}
Main execution
if [ $# -lt 1 ]; then
echo "Usage: $0 [build_id]"
echo "Environment variables:"
echo " FAIL_ON_CRITICAL=true|false (default: true)"
echo " FAIL_ON_HIGH=true|false (default: false)"
echo " MAX_HIGH_VULNS=N (default: 10)"
echo " SCAN_RESULTS_DIR=path (optional)"
exit 1
fi
ci_scan "$1" "$2"
Make CI script executable
Set proper permissions on the CI/CD integration script.
sudo chmod 755 /usr/local/bin/ci-security-scan
sudo chown root:root /usr/local/bin/ci-security-scan
Set up security policies and reporting
Create security policy configuration
Define organizational security policies for container image scanning and compliance.
# Container Security Policy Configuration
policy:
# Vulnerability severity thresholds
severity_thresholds:
critical: 0 # Block deployment if any critical vulns
high: 5 # Block if more than 5 high vulns
medium: 20 # Warn if more than 20 medium vulns
low: 50 # Info if more than 50 low vulns
# Scanner types to enable
scanners:
- vuln # CVE vulnerabilities
- secret # Exposed secrets/keys
- config # Configuration issues
# Base image policies
base_images:
approved:
- "docker.io/library/ubuntu:22.04"
- "docker.io/library/alpine:3.18"
- "registry.redhat.io/ubi8/ubi:latest"
blocked:
- "docker.io/library/ubuntu:16.04" # EOL
- "docker.io/library/centos:7" # EOL
# File scanning policies
file_patterns:
secrets:
- "**/.env"
- "**/config/*.key"
- "/secrets/"
configs:
- "**/nginx.conf"
- "**/apache2.conf"
- "**/ssh_config"
# Compliance requirements
compliance:
require_signed_images: true
block_unpatched_critical: true
max_image_age_days: 90
require_minimal_base: false
Create vulnerability report generator
Build a comprehensive reporting script for security scan results and trends.
#!/bin/bash
Security vulnerability reporting tool
set -e
Configuration
REPORT_DIR="/var/log/trivy/reports"
DATE=$(date +%Y-%m-%d)
REPORT_FILE="${REPORT_DIR}/security-report-${DATE}.html"
JSON_FILE="${REPORT_DIR}/security-report-${DATE}.json"
Create report directory
mkdir -p "$REPORT_DIR"
Function to scan multiple images
scan_images() {
local images=("$@")
local results="[]"
for image in "${images[@]}"; do
echo "Scanning $image..."
# Scan image
scan_file="/tmp/scan-$(echo "$image" | tr '/:' '_').json"
trivy image --format json --output "$scan_file" "$image" || {
echo "Failed to scan $image"
continue
}
# Extract summary
if [ -f "$scan_file" ]; then
critical=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL") | .VulnerabilityID' "$scan_file" 2>/dev/null | wc -l)
high=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH") | .VulnerabilityID' "$scan_file" 2>/dev/null | wc -l)
medium=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "MEDIUM") | .VulnerabilityID' "$scan_file" 2>/dev/null | wc -l)
low=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "LOW") | .VulnerabilityID' "$scan_file" 2>/dev/null | wc -l)
# Build JSON result
result=$(jq -n \
--arg image "$image" \
--arg critical "$critical" \
--arg high "$high" \
--arg medium "$medium" \
--arg low "$low" \
--arg timestamp "$(date -Iseconds)" \
'{
image: $image,
timestamp: $timestamp,
vulnerabilities: {
critical: ($critical | tonumber),
high: ($high | tonumber),
medium: ($medium | tonumber),
low: ($low | tonumber)
}
}')
results=$(echo "$results" | jq --argjson new "$result" '. + [$new]')
rm -f "$scan_file"
fi
done
echo "$results"
}
Function to generate HTML report
generate_html_report() {
local json_data="$1"
cat > "$REPORT_FILE" << EOF
Container Security Report - $DATE
Container Security Report
Generated: $(date)
Summary
EOF
# Calculate totals
total_images=$(echo "$json_data" | jq '. | length')
total_critical=$(echo "$json_data" | jq '[.[].vulnerabilities.critical] | add')
total_high=$(echo "$json_data" | jq '[.[].vulnerabilities.high] | add')
total_medium=$(echo "$json_data" | jq '[.[].vulnerabilities.medium] | add')
total_low=$(echo "$json_data" | jq '[.[].vulnerabilities.low] | add')
cat >> "$REPORT_FILE" << EOF
Total Images Scanned: $total_images
Total Critical Vulnerabilities: $total_critical
Total High Vulnerabilities: $total_high
Total Medium Vulnerabilities: $total_medium
Total Low Vulnerabilities: $total_low
Detailed Results
Image
Critical
High
Medium
Low
Scan Time
EOF
# Add table rows
echo "$json_data" | jq -r '.[] | "\(.image) \(.vulnerabilities.critical) \(.vulnerabilities.high) \(.vulnerabilities.medium) \(.vulnerabilities.low) \(.timestamp) "' >> "$REPORT_FILE"
cat >> "$REPORT_FILE" << EOF
EOF
}
Main execution
if [ $# -eq 0 ]; then
echo "Usage: $0 [image2] [image3] ..."
echo "Example: $0 nginx:latest alpine:latest ubuntu:22.04"
exit 1
fi
echo "Generating security report for ${#@} images..."
Scan all provided images
results=$(scan_images "$@")
Save JSON results
echo "$results" | jq '.' > "$JSON_FILE"
Generate HTML report
generate_html_report "$results"
echo "Reports generated:"
echo " JSON: $JSON_FILE"
echo " HTML: $REPORT_FILE"
Display summary
echo
echo "Summary:"
echo "$results" | jq -r '.[] | "\(.image): \(.vulnerabilities.critical) critical, \(.vulnerabilities.high) high"'
Make report generator executable
Set proper permissions on the security report generation script.
sudo chmod 755 /usr/local/bin/generate-security-report
sudo chown root:root /usr/local/bin/generate-security-report
Create log rotation configuration
Set up log rotation to manage Trivy scan logs and prevent disk space issues.
/var/log/trivy/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 0644 root root
postrotate
/usr/bin/systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
/var/log/trivy/reports/*.json {
weekly
missingok
rotate 12
compress
delaycompress
notifempty
create 0644 root root
}
Verify your setup
Test basic Trivy functionality
Verify that Trivy can scan images and detect vulnerabilities.
trivy --version
trivy image --severity HIGH,CRITICAL alpine:latest
Test Podman scanning integration
Use the scanning wrapper script to test the integration workflow.
podman-scan pull-scan nginx:latest
echo $?
Test CI/CD integration script
Verify the CI/CD scanning script works with different policy configurations.
FAIL_ON_CRITICAL=true ci-security-scan alpine:latest test-build-001
FAIL_ON_HIGH=true MAX_HIGH_VULNS=0 ci-security-scan ubuntu:latest test-build-002
Generate a sample security report
Create a comprehensive security report to verify reporting functionality.
generate-security-report nginx:latest alpine:latest ubuntu:22.04
ls -la /var/log/trivy/reports/
Check systemd timer status
Verify that the vulnerability database update timer is functioning correctly.
sudo systemctl status trivy-db-update.timer
sudo systemctl list-timers trivy-db-update.timer
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Database download fails | Network connectivity or firewall | Check internet access and proxy settings: curl -I https://github.com |
| Permission denied on scan files | Incorrect directory ownership | Fix ownership: sudo chown -R $USER:$USER /var/lib/trivy |
| JSON parsing errors in scripts | Missing jq package or malformed JSON | Install jq and validate JSON: sudo apt install -y jq |
| CI scan timeouts | Large images or slow network | Increase timeout: export SCAN_TIMEOUT=600 |
| Systemd timer not running | Timer not enabled or service failed | Check logs: sudo systemctl status trivy-db-update.service |
| High memory usage during scans | Large container images | Scan images individually and use --light flag |
| False positive vulnerabilities | Outdated vulnerability database | Update database: trivy image --download-db-only |
| Report generation fails | Missing write permissions | Create directory: sudo mkdir -p /var/log/trivy/reports && sudo chown $USER:$USER /var/log/trivy/reports |
Next steps
- Set up Falco runtime security monitoring to detect threats during container execution
- Configure Kubernetes network policies for container network security
- Integrate Prometheus monitoring to track security scan metrics and trends
- Build Grafana dashboards for visualizing container security posture
- Implement container image signing with Cosign for supply chain security
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration variables
TRIVY_CONFIG="/etc/trivy/trivy.yaml"
TRIVY_CACHE_DIR="/var/lib/trivy"
SCAN_SCRIPT="/usr/local/bin/podman-scan"
# Cleanup function for error handling
cleanup() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
rm -f "$SCAN_SCRIPT" 2>/dev/null || true
rm -rf "$TRIVY_CACHE_DIR" 2>/dev/null || true
rm -f /etc/systemd/system/trivy-db-update.* 2>/dev/null || true
systemctl daemon-reload 2>/dev/null || true
}
trap cleanup ERR
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root or with sudo${NC}"
exit 1
fi
# Auto-detect distribution
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Cannot detect distribution. /etc/os-release not found.${NC}"
exit 1
fi
echo -e "${BLUE}Installing Podman with Trivy security scanning on $PRETTY_NAME${NC}"
echo
# Step 1: Update system packages
echo -e "${YELLOW}[1/8] Updating system packages...${NC}"
$PKG_UPDATE
echo -e "${GREEN}✓ System packages updated${NC}"
echo
# Step 2: Install Podman
echo -e "${YELLOW}[2/8] Installing Podman...${NC}"
$PKG_INSTALL podman
echo -e "${GREEN}✓ Podman installed${NC}"
echo
# Step 3: Install prerequisites for Trivy
echo -e "${YELLOW}[3/8] Installing prerequisites...${NC}"
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_INSTALL wget apt-transport-https gnupg lsb-release jq
else
$PKG_INSTALL wget jq
fi
echo -e "${GREEN}✓ Prerequisites installed${NC}"
echo
# Step 4: Install Trivy security scanner
echo -e "${YELLOW}[4/8] Installing Trivy security scanner...${NC}"
if [[ "$PKG_MGR" == "apt" ]]; then
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add -
echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" > /etc/apt/sources.list.d/trivy.list
apt update
$PKG_INSTALL trivy
else
cat > /etc/yum.repos.d/trivy.repo << 'EOF'
[trivy]
name=Trivy repository
baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$basearch/
gpgcheck=0
enabled=1
EOF
$PKG_INSTALL trivy
fi
echo -e "${GREEN}✓ Trivy installed${NC}"
echo
# Step 5: Configure Trivy
echo -e "${YELLOW}[5/8] Configuring Trivy...${NC}"
mkdir -p /etc/trivy "$TRIVY_CACHE_DIR"
cat > "$TRIVY_CONFIG" << 'EOF'
cache:
dir: /var/lib/trivy
format: json
severity:
- UNKNOWN
- LOW
- MEDIUM
- HIGH
- CRITICAL
scan:
skip-dirs:
- /usr/share/man
- /tmp
skip-files:
- "*.md"
- "*.txt"
timeout: 600
vulnerability:
type:
- os
- library
secret:
config: /etc/trivy/secret.yaml
EOF
chown -R root:root /etc/trivy "$TRIVY_CACHE_DIR"
chmod 755 /etc/trivy "$TRIVY_CACHE_DIR"
chmod 644 "$TRIVY_CONFIG"
echo -e "${GREEN}✓ Trivy configured${NC}"
echo
# Step 6: Create scanning wrapper script
echo -e "${YELLOW}[6/8] Creating scanning wrapper script...${NC}"
cat > "$SCAN_SCRIPT" << 'EOF'
#!/usr/bin/env bash
set -euo pipefail
TRIVY_CONFIG="/etc/trivy/trivy.yaml"
SCAN_REPORTS_DIR="/var/log/trivy"
# Create reports directory
mkdir -p "$SCAN_REPORTS_DIR"
scan_image() {
local image="$1"
local timestamp=$(date +%Y%m%d_%H%M%S)
local output_file="$SCAN_REPORTS_DIR/scan_${image//\//_}_${timestamp}.json"
echo "Scanning image: $image"
trivy image \
--config "$TRIVY_CONFIG" \
--format json \
--output "$output_file" \
"$image"
critical_count=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "CRITICAL") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
high_count=$(jq -r '.Results[]?.Vulnerabilities[]? | select(.Severity == "HIGH") | .VulnerabilityID' "$output_file" 2>/dev/null | wc -l)
echo "Critical vulnerabilities: $critical_count"
echo "High vulnerabilities: $high_count"
trivy image \
--config "$TRIVY_CONFIG" \
--format table \
--severity HIGH,CRITICAL \
"$image"
if [ "$critical_count" -gt 0 ]; then
echo "ERROR: Critical vulnerabilities found in $image"
return 1
elif [ "$high_count" -gt 5 ]; then
echo "WARNING: More than 5 high-severity vulnerabilities found in $image"
return 2
fi
echo "Image $image passed security scan"
return 0
}
pull_and_scan() {
local image="$1"
echo "Pulling image: $image"
podman pull "$image"
echo "Scanning pulled image..."
scan_image "$image"
}
case "$1" in
scan)
if [ -z "${2:-}" ]; then
echo "Usage: $0 scan <image>"
exit 1
fi
scan_image "$2"
;;
pull-scan)
if [ -z "${2:-}" ]; then
echo "Usage: $0 pull-scan <image>"
exit 1
fi
pull_and_scan "$2"
;;
*)
echo "Usage: $0 {scan|pull-scan} <image>"
echo " scan - Scan existing local image"
echo " pull-scan - Pull image from registry and scan"
exit 1
;;
esac
EOF
chown root:root "$SCAN_SCRIPT"
chmod 755 "$SCAN_SCRIPT"
echo -e "${GREEN}✓ Scanning script created${NC}"
echo
# Step 7: Set up systemd services for automatic updates
echo -e "${YELLOW}[7/8] Setting up automatic database updates...${NC}"
cat > /etc/systemd/system/trivy-db-update.service << 'EOF'
[Unit]
Description=Update Trivy vulnerability database
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/bin/trivy image --download-db-only
Environment=TRIVY_CACHE_DIR=/var/lib/trivy
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/trivy-db-update.timer << 'EOF'
[Unit]
Description=Update Trivy database daily
Requires=trivy-db-update.service
[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1800
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable trivy-db-update.timer
systemctl start trivy-db-update.timer
echo -e "${GREEN}✓ Automatic updates configured${NC}"
echo
# Step 8: Verification
echo -e "${YELLOW}[8/8] Verifying installation...${NC}"
# Check Podman installation
if ! command -v podman &> /dev/null; then
echo -e "${RED}✗ Podman not found${NC}"
exit 1
fi
echo -e "${GREEN}✓ Podman is installed${NC}"
# Check Trivy installation
if ! command -v trivy &> /dev/null; then
echo -e "${RED}✗ Trivy not found${NC}"
exit 1
fi
echo -e "${GREEN}✓ Trivy is installed${NC}"
# Initial database download
echo "Downloading initial vulnerability database..."
trivy image --download-db-only
echo -e "${GREEN}✓ Vulnerability database downloaded${NC}"
# Test scan script
if [[ -x "$SCAN_SCRIPT" ]]; then
echo -e "${GREEN}✓ Scanning script is executable${NC}"
else
echo -e "${RED}✗ Scanning script not executable${NC}"
exit 1
fi
# Check systemd timer
if systemctl is-active --quiet trivy-db-update.timer; then
echo -e "${GREEN}✓ Automatic updates are active${NC}"
else
echo -e "${RED}✗ Automatic updates not active${NC}"
exit 1
fi
echo
echo -e "${GREEN}Installation completed successfully!${NC}"
echo
echo -e "${BLUE}Usage examples:${NC}"
echo " $SCAN_SCRIPT scan nginx:latest"
echo " $SCAN_SCRIPT pull-scan alpine:latest"
echo
echo -e "${BLUE}Scan reports are saved to: /var/log/trivy/${NC}"
echo -e "${BLUE}Configuration file: $TRIVY_CONFIG${NC}"
Review the script before running. Execute with: bash install.sh