docker-containerization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDocker 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
undefineddockerfile
undefinedMulti-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"]
undefinedRUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]
undefined2. Optimization Techniques
2. 优化技巧
Layer Caching
层缓存
dockerfile
undefineddockerfile
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 . .
undefinedFROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
undefinedMinimize Image Size
最小化镜像大小
dockerfile
undefineddockerfile
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
undefinedFROM python:3.11-alpine
undefined3. Security Best Practices
3. 安全最佳实践
dockerfile
FROM node:18-alpinedockerfile
FROM node:18-alpineUpdate 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
undefinedundefined4. Environment Configuration
4. 环境配置
dockerfile
undefineddockerfile
undefinedUse 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
CMD node healthcheck.js || exit 1
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s
CMD node healthcheck.js || exit 1
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"
version="1.0.0"
description="Production API service"
undefinedLABEL maintainer="team@example.com"
version="1.0.0"
description="Production API service"
version="1.0.0"
description="Production API service"
undefined5. Docker Compose for Multi-Container
5. Docker Compose 多容器部署
yaml
undefinedyaml
undefineddocker-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:
undefinedversion: '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:
undefined6. .dockerignore File
6. .dockerignore 文件
undefinedundefined.dockerignore
.dockerignore
node_modules
npm-debug.log
dist
.git
.env
.env.local
*.md
!README.md
.DS_Store
coverage
.vscode
.idea
pycache
*.pyc
.pytest_cache
undefinednode_modules
npm-debug.log
dist
.git
.env
.env.local
*.md
!README.md
.DS_Store
coverage
.vscode
.idea
pycache
*.pyc
.pytest_cache
undefinedBest 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 /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 /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 /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 /app/main .
CMD ["./main"]Useful Commands
常用命令
bash
undefinedbash
undefinedBuild 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
undefineddocker system prune -a
undefinedTroubleshooting
故障排查
Container exits immediately:
bash
docker logs container-name
docker inspect container-nameBuild 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