🛠️ Lab 3 — Shrink, Tag, Push, and Scan an AI Inference Image (50 pts)

Goal: Containerize a small scikit-learn inference app in a single-stage Dockerfile, measure its size, refactor it into a multi-stage build, then tag it with semantic versions, push it to Docker Hub, and scan it with Trivy. Steps:

  1. Confirm Docker Desktop (or Docker Engine) is installed and running: docker --version.
  2. Create a project folder (week03-lab) with train_and_serve.py (< 30 lines) that trains a classifier on sklearn.datasets.load_iris(), saves it with joblib, reloads it, and prints a sample prediction. Add a requirements.txt (e.g. scikit-learn, joblib).
  3. Write a single-stage Dockerfile: FROM python:3.11, COPY requirements.txt and pip install -r requirements.txt, then COPY your script and set it as CMD. Build and tag: docker build -t iris-classifier:single-stage .. Check size with docker image ls and record it. Run with docker run --rm iris-classifier:single-stage to confirm the prediction prints.
  4. Refactor into a multi-stage Dockerfile: a builder stage FROM python:3.11 installs dependencies; a final stage FROM python:3.11-slim uses COPY --from=builder to bring across only installed packages and your script. Add a non-root user (RUN useradd -m appuser, USER appuser, COPY --chown=appuser:appuser).
  5. Build: docker build -t iris-classifier:multi-stage .. Check size again, calculate the percentage reduction versus single-stage, and run it to confirm the prediction is still correct.
  6. Create a free Docker Hub account if needed, then docker login.
  7. Tag the multi-stage image with semantic versions: docker tag iris-classifier:multi-stage <username>/iris-classifier:v1.0.0 and <username>/iris-classifier:latest. Push both: docker push <username>/iris-classifier:v1.0.0 then ...:latest. Confirm both tags appear on your Docker Hub repo page.
  8. Install Trivy locally (pip install trivy or the single-binary release for your OS); verify with trivy --version. Scan your pushed image: trivy image <username>/iris-classifier:v1.0.0.
  9. Document findings in a table (Severity, CVE ID, Affected Package) — include every CRITICAL/HIGH finding, summarizing MEDIUM/LOW in one row if there are many.
  10. Write a short report (half a page): your before/after image sizes and percentage reduction, one sentence on why the non-root user matters here, and one sentence on whether your Trivy findings would pass or fail a CRITICAL/HIGH CI severity gate.

Deliverables: Both Dockerfiles, train_and_serve.py, requirements.txt, a screenshot or text export of your Docker Hub tags page, your Trivy findings table, and your written report (file upload or pasted text).