Docker 安装 Python
Python 镜像选型、依赖安装、多阶段瘦身。
Key Points生产用 python:3.12-slim;先 COPY requirements.txt 再装依赖,能吃到缓存;需要编译的包在多阶段里编完再拷过去。
直接跑
Bash
docker run -it --rm -v "$PWD:/app" -w /app python:3.12-slim bash
pip install -r requirements.txt
python app.py生产 Dockerfile
Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
COPY --from=builder /wheels /wheels
COPY requirements.txt .
RUN pip install --no-cache-dir --no-index --find-links=/wheels -r requirements.txt \
&& rm -rf /wheels
COPY . .
RUN useradd -m app && chown -R app /app
USER app
EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]为什么这么写
PYTHONUNBUFFERED=1—— 日志立刻刷出,否则docker logs看不到实时输出- 先 wheel 后 install —— 编译工具留在 builder,运行镜像里没有 gcc
--no-cache-dir—— 不把 pip 缓存打进镜像- 非 root 用户 —— 降低容器逃逸后的影响
镜像怎么选
| Tag | Size | Note |
|---|---|---|
python:3.12 | ~1GB | Includes build tools |
python:3.12-slim | ~130MB | Recommended for prod |
python:3.12-alpine | ~50MB | musl: many wheels unavailable |
On alpine, numpy and pandas often compile from source, multiplying build time. Use slim unless size is a hard requirement.
直接跑
Bash
docker run -it --rm -v "$PWD:/app" -w /app python:3.12-slim bash
pip install -r requirements.txt
python app.py生产 Dockerfile
Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends build-essential \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
COPY --from=builder /wheels /wheels
COPY requirements.txt .
RUN pip install --no-cache-dir --no-index --find-links=/wheels -r requirements.txt \
&& rm -rf /wheels
COPY . .
RUN useradd -m app && chown -R app /app
USER app
EXPOSE 8000
CMD ["gunicorn", "-b", "0.0.0.0:8000", "app:app"]为什么这么写
PYTHONUNBUFFERED=1—— 日志立刻刷出,否则docker logs看不到实时输出- 先 wheel 后 install —— 编译工具留在 builder,运行镜像里没有 gcc
--no-cache-dir—— 不把 pip 缓存打进镜像- 非 root 用户 —— 降低容器逃逸后的影响
镜像怎么选
| 标签 | 体积 | 说明 |
|---|---|---|
python:3.12 | ~1GB | 含编译工具 |
python:3.12-slim | ~130MB | 生产推荐 |
python:3.12-alpine | ~50MB | musl:很多 wheel 不可用 |
alpine 上装 numpy / pandas 往往要现场编译,构建时间翻几倍。除非体积是硬指标,用 slim。