Module 15 Lesson 3: Capstone: Protected Images
·DevOps

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

  1. Tiny Base: We use python-slim, which has 200 fewer "Attack Tools" than the standard Python image.
  2. No Compilers: We install gcc to build our libraries in the builder stage, but we don't copy it to the final image. An attacker cannot compile their own malware inside our container.
  3. 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

  1. Build both images for the GlobalHealth platform.
  2. Run docker scout quickview backend-image. How many "High" vulnerabilities are left?
  3. If you find a vulnerability in a library (like requests or flask), where should you fix it? (The Dockerfile or requirements.txt?)
  4. Why did we use chown -R healthuser before switching to USER 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.

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn