Dockerfile 与 Compose 实战

知识库
知识库文档
/tech-stacks/docker/examples/Dockerfile 与 Compose 实战.md

文档

Dockerfile 与 Docker Compose 实战

目标

编写 Dockerfile 容器化一个 Python Web 应用,并用 Docker Compose 编排多服务。

完整代码

示例应用(app/main.py)

from flask import Flask
import os
import socket

app = Flask(__name__)

@app.route('/')
def hello():
    return f"Hello from {socket.gethostname()} | ENV={os.getenv('ENV', 'dev')}"

@app.route('/health')
def health():
    return {"status": "ok"}

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Dockerfile

# ===== 多阶段构建 =====
# 阶段1:构建依赖
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# 阶段2:运行镜像
FROM python:3.12-slim
WORKDIR /app

# 创建非 root 用户
RUN useradd -m -s /bin/bash appuser

# 从 builder 复制依赖
COPY --from=builder /root/.local /home/appuser/.local
COPY app/ ./app/

# 切换到非 root 用户
USER appuser

ENV PATH=/home/appuser/.local/bin:$PATH
ENV ENV=production

EXPOSE 5000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:5000/health || exit 1

CMD ["python", "app/main.py"]

docker-compose.yml

version: '3.9'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: flask-app
    ports:
      - "5000:5000"
    environment:
      - ENV=production
      - REDIS_URL=redis://redis:6379
    depends_on:
      redis:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - app-network

  redis:
    image: redis:7-alpine
    container_name: redis
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
    restart: unless-stopped
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  redis-data:

运行步骤

# 构建并启动
docker compose up -d --build

# 查看状态
docker compose ps

# 查看日志
docker compose logs -f app

# 测试
curl http://localhost:5000/
curl http://localhost/       # 通过 Nginx 代理

# 停止
docker compose down

预期输出

Hello from <container-id> | ENV=production

信息

路径
/tech-stacks/docker/examples/Dockerfile 与 Compose 实战.md
更新时间
2026/5/31