| name | docker-containerization |
| description | Create optimized Docker containers with multi-stage builds, security best practices, and minimal image sizes. Use when containerizing applications, creating Dockerfiles, optimizing container images, or setting up Docker Compose services. |
Docker Containerization
Overview
Build production-ready Docker containers following best practices for security, performance, and maintainability.
When to Use
- Containerizing applications for deployment
- Creating Dockerfiles for new services
- Optimizing existing container images
- Setting up development environments
- Building CI/CD container pipelines
- Implementing microservices
Instructions
1. Multi-Stage Builds
# Multi-stage build for Node.js application
# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Stage 2: Production
FROM node:18-alpine
WORKDIR /app
# Copy only production dependencies and built files
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package*.json ./
# Security: Run as non-root user
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]
2. Optimization Techniques
Layer Caching
# ❌ Poor caching - changes in source code invalidate dependency install
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
# ✅ Good caching - dependencies cached separately
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
Minimize Image Size
# ❌ Large image (~800MB)
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3 python3-pip
# ✅ Minimal image (~50MB)
FROM python:3.11-alpine
3. Security Best Practices
FROM node:18-alpine
# Update packages for security patches
RUN apk update && apk upgrade
# Don't run as root
RUN addgroup -g 1001 appgroup && adduser -S -u 1001 -G appgroup appuser
USER appuser
# Use specific versions, not 'latest'
WORKDIR /app
# Scan for vulnerabilities
# Run: docker scan your-image:tag
4. Environment Configuration
# Use build arguments for flexibility
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
CMD node healthcheck.js || exit 1
# Labels for metadata
LABEL maintainer="team@example.com" \
version="1.0.0" \
description="Production API service"
5. Docker Compose for Multi-Container
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
NODE_ENV: production
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- app-network
volumes:
- ./uploads:/app/uploads
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD: password
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
postgres-data:
redis-data:
6. .dockerignore File
# .dockerignore
node_modules
npm-debug.log
dist
.git
.env
.env.local
*.md
!README.md
.DS_Store
coverage
.vscode
.idea
__pycache__
*.pyc
.pytest_cache
Best Practices
✅ DO
- Use official base images
- Implement multi-stage builds
- Run as non-root user
- Use .dockerignore
- Pin specific versions
- Include health checks
- Scan for vulnerabilities
- Minimize layers
- Use build caching effectively
❌ DON'T
- Use 'latest' tag in production
- Run as root user
- Include secrets in images
- Create unnecessary layers
- Install unnecessary packages
- Ignore security updates
- Store data in containers
Examples by Language
Python (Django/Flask)
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m appuser && chown -R appuser:appuser /app
USER appuser
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Java (Spring Boot)
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
RUN addgroup -S spring && adduser -S spring -G spring
USER spring
ENTRYPOINT ["java", "-jar", "app.jar"]
Go
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
Useful Commands
# Build image
docker build -t myapp:1.0.0 .
# Build with cache disabled
docker build --no-cache -t myapp:1.0.0 .
# Run container
docker run -d -p 3000:3000 --name myapp myapp:1.0.0
# View logs
docker logs -f myapp
# Execute command in container
docker exec -it myapp sh
# Inspect image layers
docker history myapp:1.0.0
# Check image size
docker images myapp
# Clean up
docker system prune -a
Troubleshooting
Container exits immediately:
docker logs container-name
docker inspect container-name
Build fails:
docker build --progress=plain -t myapp .
Permission issues: Ensure proper user setup and volume permissions.
Large image size:
- Use alpine base images
- Implement multi-stage builds
- Remove unnecessary files
- Use .dockerignore