Here is an example of an optimized Dockerfile, demonstrating a multi-stage build for a Python application. This approach separates build-time dependencies and tools from the final runtime image, significantly reducing its size. The goal is to move from a hypothetical 1.2GB image to under 150MB by using minimal base images and carefully copying only necessary artifacts. A simple docker-compose.yml snippet is also included for local testing.
Optimized Dockerfile
```dockerfile # Stage 1: Builder - Install application dependencies # Uses a 'slim-buster' base for installing Python packages, including any C extensions. FROM python:3.9-slim-buster as builder
# Set working directory for the build process. WORKDIR /app
# Install build tools like 'build-essential' if Python packages require compilation. # Clean up apt caches immediately to avoid carrying unnecessary data. RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ && rm -rf /var/lib/apt/lists/*
# Copy 'requirements.txt' first to use Docker layer caching. # Only reinstall dependencies if this file changes. COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt
# Copy the remaining application source code. COPY . .
# Stage 2: Production - Create a minimal runtime image # Uses a 'python:alpine' base for a significantly smaller final image. FROM python:3.9-alpine
# Create a dedicated non-root user and group ('appuser', 'appgroup') for security. # This minimizes potential attack surface by not running as root. RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser
# Set the working directory for the application's runtime. WORKDIR /app
# Copy only the installed Python packages from the builder stage. # This leaves behind build tools and intermediate files. COPY --from=builder /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages # Copy the application code from the builder stage. COPY --from=builder /app /app
# Declare the port the application expects to listen on. EXPOSE 8000
# Define the default command to execute when the container starts. CMD ["python", "app.py"] ```
Docker Compose Snippet
This docker-compose.yml provides a basic configuration to build and run the optimized application image locally. It maps the container's exposed port to the host and sets a production environment variable.
``yaml version: '3.8' services: my-app: build: context: . dockerfile: Dockerfile ports: - "8000:8000" environment: - APP_ENV=production # Add other production environment variables as needed, e.g., database connection strings. # - DATABASE_URL=postgres://user:pass@db:5432/myapp ``