关键在于精简Docker镜像:选python:3.10-slim(静态爬取)或python:3.10-bookworm(需Chromium),避免冗余基础镜像;优化COPY/RUN顺序以提升构建速度;按实际运行模式决定EXPOSE与CMD;补全TZ、LANG、SIGTERM处理确保生产稳定。

直接能跑的 Python 爬虫 Dockerfile,关键不在“写全”,而在“删干净”——删掉本地开发时用的、但容器里根本不需要的东西,否则镜像臃肿、启动慢、还容易出错。
基础镜像选 python:3.10-slim 还是 selenium/standalone-chrome?
取决于你用不用浏览器自动化:
- 纯
requests/httpx/scrapy爬静态页 → 用python:3.10-slim,体积小、启动快、攻击面小 - 需要
selenium+ Chrome 执行 JS → 别直接拉selenium/standalone-chrome镜像(它自带服务端,不适合当爬虫执行环境),改用python:3.10-bookworm自己装 Chromium + chromedriver - 误用
ubuntu:22.04或centos:7基础镜像 → 会多出大量无用包,pip 安装慢、镜像超 500MB,不必要
COPY 和 RUN 的顺序不能颠倒
常见错误是把 COPY . /app 放在 RUN pip install -r requirements.txt 前面。结果:每次改一行代码,Docker 构建都会重新安装全部依赖——因为 COPY 触发了缓存失效。
正确顺序是:
立即学习“Python免费学习笔记(深入)”;
COPY requirements.txt .-
RUN pip install --no-cache-dir -r requirements.txt(加--no-cache-dir避免缓存占层空间) -
COPY ./app /app(只复制源码,不带 .git、__pycache__、.vscode 等)
这样改代码只重建最后一层,构建速度快 3–5 倍。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
EXPOSE 和 CMD 要匹配实际行为
很多爬虫是脚本型(非 Web 服务),根本不需要暴露端口。但有人习惯性写 EXPOSE 8000,甚至配 -p 8000:8000 启动,结果容器秒退——因为 main.py 执行完就退出,不是常驻进程。
判断依据很简单:
- 你的入口文件最后是不是
if __name__ == "__main__": run_spider()这种一次性逻辑 → 不需要EXPOSE,也不该加-d后台运行(除非你明确要守护模式) - 用了
APScheduler或while True:循环 → 可以加HEALTHCHECK,但依然不需要EXPOSE - 真有 Web 接口(比如 FastAPI 提供调度 API)→ 才需
EXPOSE 8000,且CMD必须是长期运行命令,如["uvicorn", "app.main:app", "--host", "0.0.0.0:8000"]
时区、编码、信号处理这些细节最容易漏
不设时区,datetime.now() 返回 UTC 时间,日志和定时任务全乱;不设 LANG=C.UTF-8,中文字段可能报 UnicodeEncodeError;没处理 SIGTERM,docker stop 会强制 kill,正在写的文件可能损坏。
最小必要补丁:
ENV TZ=Asia/Shanghai LANG=C.UTF-8RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone- Python 入口文件里加
import signal; signal.signal(signal.SIGTERM, lambda s, f: exit(0))(简单粗暴但有效)
真正难的是:这些配置在本地测不出问题,一上生产就暴露——因为宿主机时区/语言环境往往和容器不同,而你本地调试时又默认复用了宿主机设置。

















