Python Docker 部署
用容器打包解释器、依赖与入口;多阶段构建减小镜像并固定依赖。
#type / howto
#status / growing
#tech / dev
#resource / python
#tech / lang / python
[!info] 关联笔记
Python Docker 部署
目标
得到可复现运行的容器镜像:固定 Python 版本与依赖,提供合理入口与信号处理。
这个场景为什么出现
“在我机器能跑”不够。容器固化运行时,是部署与扩缩的基础单元。
[!abstract] 一句话理解 镜像 = 基础解释器 + 安装依赖 + 应用代码 + 入口命令;构建可重复,配置经环境注入。
最小示例(Dockerfile 形态)
场景:API 服务镜像骨架
# 示例骨架(教学)
FROM python:3.12-slim AS base
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src ./src
CMD ["python", "-m", "myapp"]
建议运行(需 Docker 环境):
docker build -t myapp:dev .
docker run --rm -e DATABASE_URL=... -p 8000:8000 myapp:dev
结合场景再看三个关注点
- 依赖层缓存:先 copy 锁文件。
- 非 root 用户 更安全。
- SIGTERM 传到 Python 进程以优雅关闭。
核心概念与准确模型
- 基础镜像选择
- 多阶段:构建与运行分离
- 健康检查
- 只读层与卷
边界情况与反直觉行为
- 胖镜像 攻击面大
- 本地路径依赖 进不了镜像
- GIL/worker 数 与 CPU 限额
常见误区
[!warning] 常见误区:在容器里 pip install 最新无钉版本 错误理解:永远最新最好。
正确模型:锁文件可复现构建。
工程实践
.dockerignore- CI 构建并扫描
- 配置全走环境变量
本节总结
容器是交付包装。可复现与信号/配置正确,比“能 build 通”更重要。
自测题
- 为何先复制 requirements?
- PYTHONUNBUFFERED 作用?
参考答案
- 利用层缓存,代码变更不重装依赖。
- 让日志及时输出,便于容器采集。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Docker docs | 文档 | 容器 |
| Python slim images | 镜像 | 官方基础镜像 |