Docker 容器化部署

Docker 容器化部署

概述

Docker 容器化使爬虫项目具备可移植性、可扩展性和易维护性。本章介绍如何将爬虫项目容器化并进行生产部署。


Docker 基础

核心概念

  • 镜像 (Image): 只读模板,包含运行应用所需的一切
  • 容器 (Container): 镜像的运行实例
  • Dockerfile: 构建镜像的脚本
  • Docker Compose: 多容器编排工具

Dockerfile 编写

爬虫项目 Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 使用官方 Python 镜像
FROM python:3.11-slim

# 设置工作目录
WORKDIR /app

# 安装系统依赖
RUN apt-get update && apt-get install -y \
gcc \
g++ \
wget \
&& rm -rf /var/lib/apt/lists/*

# 复制依赖文件
COPY requirements.txt .

# 安装 Python 依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制项目代码
COPY . .

# 暴露端口(如果有 API)
EXPOSE 8000

# 设置环境变量
ENV PYTHONUNBUFFERED=1

# 运行爬虫
CMD ["python", "main.py"]

Puppeteer/Playwright Dockerfile

需要安装浏览器依赖:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
FROM node:18-slim

# 安装 Chromium 依赖
RUN apt-get update && apt-get install -y \
chromium \
fonts-liberation \
libappindicator3-1 \
libasound2 \
libatk-bridge2.0-0 \
libatk1.0-0 \
libcups2 \
libdbus-1-3 \
libgdk-pixbuf2.0-0 \
libnspr4 \
libnss3 \
libx11-xcb1 \
libxcomposite1 \
libxdamage1 \
libxrandr2 \
xdg-utils \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

CMD ["node", "index.js"]

Docker Compose

完整爬虫系统编排

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
version: "3.8"

services:
# Redis
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped

# MongoDB
mongodb:
image: mongo:6
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: password
volumes:
- mongo_data:/data/db
restart: unless-stopped

# 爬虫 Master
spider-master:
build: .
command: python master.py
depends_on:
- redis
- mongodb
environment:
- REDIS_URL=redis://redis:6379
- MONGO_URL=mongodb://admin:${MONGO_PASSWORD}@mongodb:27017
restart: unless-stopped

# 爬虫 Worker
spider-worker:
build: .
command: python worker.py
depends_on:
- redis
- mongodb
environment:
- REDIS_URL=redis://redis:6379
- MONGO_URL=mongodb://admin:${MONGO_PASSWORD}@mongodb:27017
restart: unless-stopped
deploy:
replicas: 3 # 启动3个Worker

volumes:
redis_data:
mongo_data:

启动和管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 构建镜像
docker-compose build

# 启动所有服务
docker-compose up -d

# 查看日志
docker-compose logs -f spider-worker

# 扩展 Worker 数量
docker-compose up -d --scale spider-worker=5

# 停止所有服务
docker-compose down

# 停止并删除卷
docker-compose down -v

最佳实践

1. 多阶段构建

减小镜像体积:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 构建阶段
FROM python:3.11 AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# 运行阶段
FROM python:3.11-slim

WORKDIR /app

# 从构建阶段复制依赖
COPY --from=builder /root/.local /root/.local
COPY . .

ENV PATH=/root/.local/bin:$PATH

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

2. 使用 .dockerignore

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
__pycache__
*.pyc
*.pyo
*.pyd
.Python
.env
venv/
.git
.gitignore
*.md
.pytest_cache
.coverage
htmlcov/

3. 健康检查

1
2
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8000/health')" || exit 1

4. 环境变量管理

1
2
3
4
5
# docker-compose.yml
services:
spider:
env_file:
- .env
1
2
3
4
# .env 文件
REDIS_URL=redis://redis:6379
API_KEY=your_api_key_here
PROXY_URL=http://proxy.example.com

生产部署

使用 Docker Swarm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 初始化 Swarm
docker swarm init

# 部署服务栈
docker stack deploy -c docker-compose.yml spider

# 查看服务状态
docker service ls

# 扩展服务
docker service scale spider_spider-worker=10

# 删除服务栈
docker stack rm spider

使用 Kubernetes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spider-worker
spec:
replicas: 3
selector:
matchLabels:
app: spider-worker
template:
metadata:
labels:
app: spider-worker
spec:
containers:
- name: spider
image: myregistry/spider:latest
env:
- name: REDIS_URL
value: "redis://redis:6379"
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
1
2
3
4
5
6
7
8
# 部署
kubectl apply -f deployment.yaml

# 扩展
kubectl scale deployment spider-worker --replicas=10

# 查看状态
kubectl get pods

监控与日志

日志管理

1
2
3
4
5
6
7
services:
spider:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

集成 Prometheus

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
services:
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus

grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana

常见问题

Q1: 容器内时区不正确?

1
2
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone

Q2: 如何调试容器内的应用?

1
2
3
4
5
6
7
8
# 进入容器
docker exec -it container_id /bin/bash

# 查看日志
docker logs -f container_id

# 实时查看资源使用
docker stats container_id

Q3: 如何持久化数据?

使用 Docker Volume:

1
2
3
4
5
6
7
services:
spider:
volumes:
- spider_data:/app/data

volumes:
spider_data:

相关章节


相关内容

如果这篇文章对你有帮助,请我喝杯咖啡吧~
+5 支付宝支付宝
+5 微信微信