docker-containerization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Containerization

Docker容器化

Overview

概述

Build production-ready Docker containers following best practices for security, performance, and maintainability.
遵循安全、性能和可维护性的最佳实践,构建可用于生产环境的Docker容器。

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
  • 为部署进行应用容器化
  • 为新服务创建Dockerfile
  • 优化现有容器镜像
  • 搭建开发环境
  • 构建CI/CD容器流水线
  • 实现微服务

Instructions

操作指南

1. Multi-Stage Builds

1. 多阶段构建(Multi-Stage Builds)

dockerfile
undefined
dockerfile
undefined

Multi-stage build for Node.js application

Multi-stage build for Node.js application

Stage 1: Build

Stage 1: Build

FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run 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

Stage 2: Production

FROM node:18-alpine WORKDIR /app
FROM node:18-alpine WORKDIR /app

Copy only production dependencies and built files

Copy only production dependencies and built files

COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY package*.json ./
COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY package*.json ./

Security: Run as non-root user

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"]
undefined
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001 USER nodejs
EXPOSE 3000 CMD ["node", "dist/index.js"]
undefined

2. Optimization Techniques

2. 优化技巧

Layer Caching

层缓存

dockerfile
undefined
dockerfile
undefined

❌ Poor caching - changes in source code invalidate dependency install

❌ Poor caching - changes in source code invalidate dependency install

FROM python:3.11-slim WORKDIR /app COPY . . RUN pip install -r requirements.txt
FROM python:3.11-slim WORKDIR /app COPY . . RUN pip install -r requirements.txt

✅ Good caching - dependencies cached separately

✅ 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 . .
undefined
FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . .
undefined

Minimize Image Size

最小化镜像大小

dockerfile
undefined
dockerfile
undefined

❌ Large image (~800MB)

❌ Large image (~800MB)

FROM ubuntu:latest RUN apt-get update && apt-get install -y python3 python3-pip
FROM ubuntu:latest RUN apt-get update && apt-get install -y python3 python3-pip

✅ Minimal image (~50MB)

✅ Minimal image (~50MB)

FROM python:3.11-alpine
undefined
FROM python:3.11-alpine
undefined

3. Security Best Practices

3. 安全最佳实践

dockerfile
FROM node:18-alpine
dockerfile
FROM node:18-alpine

Update packages for security patches

Update packages for security patches

RUN apk update && apk upgrade
RUN apk update && apk upgrade

Don't run as root

Don't run as root

RUN addgroup -g 1001 appgroup && adduser -S -u 1001 -G appgroup appuser USER appuser
RUN addgroup -g 1001 appgroup && adduser -S -u 1001 -G appgroup appuser USER appuser

Use specific versions, not 'latest'

Use specific versions, not 'latest'

WORKDIR /app
WORKDIR /app

Scan for vulnerabilities

Scan for vulnerabilities

Run: docker scan your-image:tag

Run: docker scan your-image:tag

undefined
undefined

4. Environment Configuration

4. 环境配置

dockerfile
undefined
dockerfile
undefined

Use build arguments for flexibility

Use build arguments for flexibility

ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV}
ARG NODE_ENV=production ENV NODE_ENV=${NODE_ENV}

Health check

Health check

HEALTHCHECK --interval=30s --timeout=3s --start-period=40s
CMD node healthcheck.js || exit 1
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s
CMD node healthcheck.js || exit 1

Labels for metadata

Labels for metadata

LABEL maintainer="team@example.com"
version="1.0.0"
description="Production API service"
undefined
LABEL maintainer="team@example.com"
version="1.0.0"
description="Production API service"
undefined

5. Docker Compose for Multi-Container

5. Docker Compose 多容器部署

yaml
undefined
yaml
undefined

docker-compose.yml

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:
undefined
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:
undefined

6. .dockerignore File

6. .dockerignore 文件

undefined
undefined

.dockerignore

.dockerignore

node_modules npm-debug.log dist .git .env .env.local *.md !README.md .DS_Store coverage .vscode .idea pycache *.pyc .pytest_cache
undefined
node_modules npm-debug.log dist .git .env .env.local *.md !README.md .DS_Store coverage .vscode .idea pycache *.pyc .pytest_cache
undefined

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
  • 使用官方基础镜像
  • 采用多阶段构建
  • 以非root用户运行
  • 使用.dockerignore
  • 固定特定版本
  • 添加健康检查
  • 扫描漏洞
  • 最小化镜像层
  • 有效利用构建缓存

❌ 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
  • 生产环境中使用'latest'标签
  • 以root用户运行
  • 在镜像中包含敏感信息
  • 创建不必要的镜像层
  • 安装不必要的软件包
  • 忽略安全更新
  • 在容器中存储数据

Examples by Language

按语言分类的示例

Python (Django/Flask)

Python(Django/Flask)

dockerfile
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"]
dockerfile
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)

Java(Spring Boot)

dockerfile
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"]
dockerfile
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

Go

dockerfile
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"]
dockerfile
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

常用命令

bash
undefined
bash
undefined

Build image

Build image

docker build -t myapp:1.0.0 .
docker build -t myapp:1.0.0 .

Build with cache disabled

Build with cache disabled

docker build --no-cache -t myapp:1.0.0 .
docker build --no-cache -t myapp:1.0.0 .

Run container

Run container

docker run -d -p 3000:3000 --name myapp myapp:1.0.0
docker run -d -p 3000:3000 --name myapp myapp:1.0.0

View logs

View logs

docker logs -f myapp
docker logs -f myapp

Execute command in container

Execute command in container

docker exec -it myapp sh
docker exec -it myapp sh

Inspect image layers

Inspect image layers

docker history myapp:1.0.0
docker history myapp:1.0.0

Check image size

Check image size

docker images myapp
docker images myapp

Clean up

Clean up

docker system prune -a
undefined
docker system prune -a
undefined

Troubleshooting

故障排查

Container exits immediately:
bash
docker logs container-name
docker inspect container-name
Build fails:
bash
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
容器立即退出:
bash
docker logs container-name
docker inspect container-name
构建失败:
bash
docker build --progress=plain -t myapp .
权限问题: 确保正确设置用户和卷权限。
镜像过大:
  • 使用alpine基础镜像
  • 采用多阶段构建
  • 删除不必要的文件
  • 使用.dockerignore