This is a sample web application showcasing a multi-tier architecture using Node.js, Python (Flask), PostgreSQL, and nginx.
The app is available in two variants:
- Legacy version with traditional upstream container images.
- Chainguard version using minimal, secure-by-default, zero to near-zero CVE container images.
- Docker
- grype (for scanning container images)
- Clone this directory and
cdinto it from your terminal:
git clone https://github.com/bakenfazer/educause && cd educausedocker compose up -d --build- Open http://localhost:80 in your browser to view the website. You should see the following:
- Check that the backend API works by running:
curl http://localhost:5000You should see the following response: Hooray! The API works.
./scanners/grype-scan.shThis will save your results to ./scanners/scan-results/grype-legacy-images.csv.
To clean everything, including volumes:
docker compose down -vdocker compose -f docker-compose-chainguard.yaml up -d --build-
Check the API:
curl http://localhost:5000/./scanners/grype-scan.shThis will save your results to ./scanners/scan-results/grype-chainguard-images.csv.
To clean everything, including volumes:
docker compose down -vAfter scanning both versions, open the CSV files to review the outputs to compare:
- Total CVEs
- Severity levels (Critical, High, etc.)
- Image size and dependency differences
This highlights the value of using Chainguard's minimal, secure-by-default images like those from Chainguard.
Compare image sizes, SBOMs, and provenance
