Dockerfile

Download
docker 71 lines 2.4 KB
 1# Multi-stage Docker build for a Python Flask application
 2# This demonstrates best practices for creating slim, secure production images
 3
 4# ============================================================================
 5# Stage 1: Builder
 6# Purpose: Install dependencies and build the application
 7# ============================================================================
 8FROM python:3.11-slim as builder
 9
10# Set working directory
11WORKDIR /app
12
13# Install build dependencies
14# These are only needed during the build process
15RUN apt-get update && apt-get install -y --no-install-recommends \
16    gcc \
17    && rm -rf /var/lib/apt/lists/*
18
19# Copy only requirements first to leverage Docker cache
20# If requirements.txt doesn't change, this layer is cached
21COPY requirements.txt .
22
23# Install Python dependencies to a local directory
24# This allows us to copy only what's needed to the final stage
25RUN pip install --user --no-cache-dir -r requirements.txt
26
27# ============================================================================
28# Stage 2: Runtime
29# Purpose: Create a minimal production image
30# ============================================================================
31FROM python:3.11-slim
32
33# Metadata labels following OCI standard
34LABEL maintainer="your-email@example.com"
35LABEL description="Flask application with multi-stage build"
36LABEL version="1.0"
37
38# Create a non-root user for security
39# Running as root in containers is a security risk
40RUN useradd -m -u 1000 appuser && \
41    mkdir -p /app && \
42    chown -R appuser:appuser /app
43
44# Set working directory
45WORKDIR /app
46
47# Copy Python packages from builder stage
48# This includes all installed dependencies without build tools
49COPY --from=builder --chown=appuser:appuser /root/.local /home/appuser/.local
50
51# Copy application code
52COPY --chown=appuser:appuser app.py .
53
54# Update PATH to include local Python packages
55ENV PATH=/home/appuser/.local/bin:$PATH
56
57# Switch to non-root user
58USER appuser
59
60# Expose port (documentation only, doesn't publish the port)
61EXPOSE 5000
62
63# Health check to verify container is running correctly
64# This is used by orchestrators like Kubernetes
65HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
66    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')" || exit 1
67
68# Use exec form for proper signal handling
69# This ensures SIGTERM is properly received for graceful shutdown
70CMD ["python", "app.py"]