用 Docker 把一个 Python 小工具打包成一次能跑的环境
一、为什么要打包
写 Python 小工具最常见的尴尬是:在自己电脑上跑得好好的,换一台机器就报错。不是缺依赖,就是 Python 版本对不上;更麻烦的是,过两个月自己再跑,环境早变了,复现不出当时的结果。
办法是把“工具 + 依赖 + 运行环境”一起装进镜像里。镜像一旦构建成功,就可以在任何装了 Docker 的机器上原样运行,不需要再配环境。
二、一个最小可用的 Dockerfile
假设小工具只有一个 main.py,依赖只有 requests,都放在 tool/ 目录下:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
ENTRYPOINT ["python", "main.py"]
这里有三个习惯值得保留:第一,用具体的 python:3.12-slim 而不是 latest,版本写死才可复现;第二,先复制 requirements.txt 再安装依赖,这样改代码不会让依赖层失效,构建更快;第三,把 main.py 单独复制,改动代码只影响最后一层。
三、输入输出用挂载解决,不要写进镜像
小工具通常要读文件、写结果。正确的做法是把数据目录挂载进来:
docker build -t mytool:1.0 .
docker run --rm -v $(pwd)/data:/data mytool:1.0 --input /data/in.csv --output /data/out.csv
这样镜像里不掺数据,数据留在宿主机上随时查看;换一份输入,不用重新构建,直接再跑一次命令就行。
四、一次构建,多次运行
构建一次之后,这个镜像就是可交付物:同事拿到 mytool:1.0 就能跑出和你一样的结果;定时任务里直接引用这个镜像,每天跑也不会因为环境漂移而翻车。如果要升级工具,改代码、重新构建、打一个新标签 mytool:1.1,旧版本随时可以回退。更新依赖时也一样:改 requirements.txt,重新构建,历史镜像还在,需要时可以随时拿出来对照。
五、几个容易踩的坑
一是把大文件塞进镜像。几百兆的数据文件不要 COPY 进镜像,会让镜像臃肿且每次构建都变慢,数据应该挂载。
二是忘记处理时区和换行。容器默认是 UTC,如果工具输出带时间,最好在 Dockerfile 里写清楚时区;Windows 上写的文件换行符也可能让脚本行为异常,尽量用 Linux 换行。
三是容器里跑完就删。调试时别急着加 --rm,先用 docker logs 看输出,确认无误后再把它写进固定命令里。
- 点赞
- 收藏
- 关注作者
评论(0)