
Module 15 Lesson 3: Capstone: Protected Images
Fortify the binary. Create production-ready, hardened Dockerfiles for the GlobalHealth platform using multi-stage builds and non-root users.
Module 15 Lesson 3: Capstone - Protected Images
Today we build the Dockerfiles for our Backend and Frontend. We will use the "Security-First" patterns we learned in Module 7 and 13.
1. The Hardened Backend (backend/Dockerfile)
# 1. Base Layer
FROM python:3.11-slim as base
ENV PIP_NO_CACHE_DIR=1
# 2. Build Stage
FROM base as builder
RUN apt-get update && apt-get install -y gcc
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# 3. Final Production Stage
FROM base
WORKDIR /app
# Create a non-root user
RUN groupadd -r healthgroup && useradd -r -g healthgroup healthuser
# Copy only the installed packages from builder
COPY --from=builder /root/.local /home/healthuser/.local
COPY . .
# Ensure permissions ARE CORRECT
RUN chown -R healthuser:healthgroup /app
USER healthuser
# Add the local pip folder to PATH
ENV PATH=/home/healthuser/.local/bin:$PATH
EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:5000/health || exit 1
CMD ["python", "main.py"]
2. Why this is Secure
- Tiny Base: We use
python-slim, which has 200 fewer "Attack Tools" than the standard Python image. - No Compilers: We install
gccto build our libraries in thebuilderstage, but we don't copy it to the final image. An attacker cannot compile their own malware inside our container. - Non-Root: Since it runs as
healthuser, even a total code takeover cannot touch the Host OS.
3. The Front-End (Static with Nginx)
(Review Module 14). We use Nginx to serve the React build. This is faster and more secure than using npm start in production.
Exercise: The Security Scan
- Build both images for the GlobalHealth platform.
- Run
docker scout quickview backend-image. How many "High" vulnerabilities are left? - If you find a vulnerability in a library (like
requestsorflask), where should you fix it? (The Dockerfile orrequirements.txt?) - Why did we use
chown -R healthuserbefore switching toUSER healthuser? What happens if you forget this line?
Summary
By building "Protected" images, you ensure that even if there is a bug in your code, the blast radius is as small as possible. This is the difference between a "Weekend project" and an "Enterprise application."
Next Lesson: The Automated Hand-off: CI/CD Deployment Strategy.