从‘它怎么又挂了’到‘服务稳如狗’:我是如何用Docker给老旧Python项目续命的
·
从“它怎么又挂了”到“服务稳如狗”:我是如何用Docker给老旧Python项目续命的
三年前接手这个“祖传”Django 1.11项目时,我天真地以为最大的挑战是理解那些写满魔法方法的代码。直到第一次在生产环境部署——pip install 报错、ImportError 连环出现、静态文件404,我才明白真正的噩梦是环境一致性。
今天分享的,不是教科书式的Docker入门教程,而是一个真实战场上的生存指南。你会看到:
- 如何用
docker build --no-cache暴力破解gcc编译依赖的玄学报错 - 用
multi-stage build把2.3GB的镜像瘦身到200MB的实操细节 - 老项目特有的
*.pyc文件缓存坑及其一键清理方案
1. 解剖“祖传”项目的依赖地狱
打开项目的requirements.txt,你可能看到这样的内容:
Django==1.11.23
celery==3.1.26.post2
MySQL-python==1.2.5 # 是的,这个包在Python 3上根本装不上
1.1 依赖冻结与兼容性分析
运行以下命令生成当前环境的真实依赖树:
pip freeze > requirements_actual.txt
diff requirements.txt requirements_actual.txt
典型问题排查表:
| 问题类型 | 解决方案 | 示例命令 |
|---|---|---|
| 缺失版本约束 | 补充==或~=版本限定符 | sed -i 's/MySQL-python/MySQL-python==1.2.5/' requirements.txt |
| 不兼容Python 3 | 寻找替代包 | 用mysqlclient替换MySQL-python |
| 依赖冲突 | 使用pip-compile生成锁定文件 | pip-compile --generate-hashes requirements.in |
1.2 构建基础镜像的智慧
不要直接使用python:3.6这样的官方镜像。基于debian:buster-slim自定义镜像能减少70%的构建体积:
FROM debian:buster-slim as builder
RUN apt-get update && apt-get install -y \
python3.6 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN ln -s /usr/bin/python3.6 /usr/bin/python
提示:老项目常需要
libssl1.0等已淘汰的库,可通过apt-get install libssl1.0-dev显式安装
2. Dockerfile中的“外科手术”
2.1 处理C扩展编译问题
当遇到error: command 'gcc' failed时,在Dockerfile中加入:
RUN apt-get update && apt-get install -y \
gcc \
python3-dev \
libmysqlclient-dev \
&& rm -rf /var/lib/apt/lists/*
2.2 静态文件收集的陷阱
老版本Django的collectstatic可能在容器中失效,需要手动指定:
docker run -e DJANGO_SETTINGS_MODULE=prod_settings \
your_image python manage.py collectstatic --noinput
3. 部署后的“老年护理”
3.1 日志监控方案
在docker-compose.yml中配置日志轮转:
services:
web:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
3.2 健康检查策略
对老项目特别重要的存活探针:
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:8000/healthz/ || exit 1
4. 那些年我们踩过的坑
4.1 时区问题终极解决方案
在Dockerfile中永久固定时区:
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
4.2 内存泄漏应急方案
限制容器内存并自动重启:
docker run -m 512m --memory-swap 1g --restart=on-failure:5 your_image
最后分享一个真实案例:某次更新后容器不断崩溃,最终发现是/tmp目录爆满。现在我会在所有Dockerfile中加入:
RUN chmod 1777 /tmp && find /tmp -type f -atime +1 -delete
更多推荐


所有评论(0)