项目容器化实战
9.1 Python 项目(Flask + PostgreSQL)
项目结构
myapp/
├── app.py
├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── .dockerignore
Dockerfile
FROM python:3.12-slim
WORKDIR /app
# 安装系统依赖
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc libpq-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# 安装 Python 依赖(利用缓存)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制代码
COPY . .
# 非 root 用户
RUN useradd -m appuser
USER appuser
EXPOSE 5000
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]
requirements.txt
flask==3.0.0
gunicorn==21.2.0
psycopg2-binary==2.9.9
docker-compose.yml
services:
web:
build: .
ports:
- "5000:5000"
environment:
DATABASE_URL: postgresql://user:pass@db:5432/mydb
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pg_data:
.dockerignore
__pycache__
*.pyc
.env
.git
*.md
常用命令
# 启动
docker compose up -d
# 查看日志
docker compose logs -f web
# 进入容器调试
docker compose exec web python -c "import flask; print(flask.__version__)"
# 查看数据库
docker compose exec db psql -U user -d mydb
9.2 Node.js 项目(Express + Redis)
Dockerfile(多阶段构建)
# 阶段 1:构建
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 阶段 2:生产运行
FROM node:20-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./
USER appuser
EXPOSE 3000
CMD ["node", "dist/server.js"]
docker-compose.yml
services:
api:
build: .
ports:
- "3000:3000"
environment:
- REDIS_HOST=redis
- NODE_ENV=production
depends_on:
- redis
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
redis_data:
9.3 Java 项目(Spring Boot + MySQL)
Dockerfile(多阶段构建)
# 阶段 1:构建
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# 阶段 2:运行
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S spring && adduser -S spring -G spring
WORKDIR /app
COPY --from=builder --chown=spring:spring /app/target/*.jar app.jar
USER spring
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
# JVM 容器感知
# Spring Boot 3.x 自动检测容器内存限制
# 旧版需要:ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-jar", "app.jar"]
docker-compose.yml
services:
app:
build: .
ports:
- "8080:8080"
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: secret
depends_on:
db:
condition: service_healthy
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: mydb
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
mysql_data:
9.4 Go 项目(静态二进制)
# 阶段 1:构建
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .
# 阶段 2:运行(scratch = 空镜像,最小体积)
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]
# 最终镜像大小:~15MB
9.5 开发环境模板
# docker-compose.dev.yml
services:
web:
build:
context: .
target: development
volumes:
- ./app:/app
- /app/node_modules
command: npm run dev
ports:
- "3000:3000"
- "9229:9229"
environment:
- NODE_ENV=development
- DEBUG=app:*
# 启动开发环境
docker compose -f docker-compose.dev.yml up
# 生产环境
docker compose -f docker-compose.prod.yml up -d
9.6 .dockerignore 通用模板
# 版本控制
.git
.gitignore
.svn
# IDE
.vscode
.idea
*.swp
*.swo
# 依赖
node_modules
vendor
__pycache__
*.pyc
.mypy_cache
.pytest_cache
# 环境配置
.env
.env.local
.env.*.local
# 文档
*.md
LICENSE
CHANGELOG.md
# Docker 相关
Dockerfile
docker-compose*.yml
.dockerignore
# 测试
test/
tests/
coverage/