Building Secure by Default A Guide to 0-CVE Container Images

Koray Ağaya16 Apr 2025
// main.go

package main

import "fmt"

func main() {
   fmt.Println("Hello from Docker!")
}
// index.js

const express = require('express');
const app = express();

app.get('/', (req, res) => res.send('Hello from Dockerized Node app!'));

app.listen(3000, () => console.log('app listening on port 3000'));
root@test:~/headless/myapp# docker images 

REPOSITORY                                      TAG         IMAGE ID         CREATED          SIZE
mynodeapp                                       latest      59a0b7136368     32 seconds ago   166MB
pid /tmp/nginx.pid; 

events {}

http {
    server {
        listen 8080;

        location / {
            return 200 'Hello from Chainguard NGINX!\n'
        }
    }
}
root@test:~/chainguard# cat Dockerile

FROM cgr.dev/chainguard/nginx:latest 

COPY ./my.conf /etc/nginx/nginx.conf
root@test:~/vex-attestation# trivy image --format cyclonedx --output sbom.json mynodeapp:latest 

2025-04-09T09Z    INFO      "--format cyclonedx" disables security scanning. Specify "--scanners vuln" explicitly if you want to include vulnerabilities in the "cyclonedx" reports
2025-04-09T09Z    INFO      Detected OS     familiy="debian" version="11.6"
2025-04-09T09Z    INFO      Number of language-specific files     num=1
- name: Generate SBOM
  run: trivy image --format cyclonedx --output sbom.json mynodeapp:latest 

- name: Validate VEX Document
  run: |
     curl -sSL https://example.com/vex-validator.sh | bash \
     --sbom sbom.json \ 
     --vex vex-cyclonedx.json
root@test:~/DIY# GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o myapp hello.go
# Dockerfile
FROM scratch
COPY myapp /myapp
ENTRYPOINT ["/myapp"]
root@test:~/DIY# trivy image --scanners vuln --skip-files /myapp --format table --no-progress zero-cve-app
2025-04-09T09Z    INFO        [vuln] Vulnerability scanning is enabled
2025-04-09T09Z    INFO        Number of langugage-specific files    num=0

Get A Demo