Nuitka 打包单个二进制的版本,这样镜像里连 .so 都没有,只有一个 ELF 可执行文件(源码完全消失,安全性比 Cython 高一档)。
假设你的入口是 main.py。
Dockerfile(Nuitka 单二进制版本)
# ===============================
# 构建阶段
# ===============================
FROM python:3.12-slim as builder
WORKDIR /app
# 环境变量
ENV PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
# 安装系统依赖和 Nuitka 所需工具
RUN apt-get update && apt-get install -y \
gcc \
g++ \
default-libmysqlclient-dev \
pkg-config \
python3-dev \
build-essential \
patchelf \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt \
&& pip install nuitka ordered-set zstandard
# 复制源码
COPY . .
# 使用 Nuitka 编译 main.py 为独立二进制
# --onefile 单文件
# --standalone 带上依赖的共享库
# --python-flag=no_site 忽略 site 包,加快启动
RUN nuitka --standalone --onefile \
--python-flag=no_site \
--output-filename=app \
main.py
# ===============================
# 运行阶段
# ===============================
FROM debian:bookworm-slim
WORKDIR /app
# 拷贝编译好的二进制和依赖
COPY --from=builder /app/app /app/app
COPY --from=builder /app/app.dist /app/app.dist
# 创建非 root 用户
RUN useradd --create-home --shell /bin/bash app \
&& chown -R app:app /app
USER app
# 健康检查(改为检测二进制是否能执行)
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD /app/app --version || exit 1
# 启动应用
CMD ["/app/app"]
说明
- 构建阶段:
- 安装 nuitka,把 main.py 编译成一个二进制 app
- app.dist 目录里存放依赖的动态库(比如 libpython)
- 删除源码,镜像中无 .py
- 运行阶段:
- 使用最小的 debian:bookworm-slim 运行时
- 只复制 app 和 app.dist
- 镜像更小,运行时安全
- 启动:
- 直接运行 /app/app,不需要 python main.py
- 从外部看起来就是一个普通的 ELF 二进制
构建 & 运行
docker build -t myapp:nuitka .
docker run --rm myapp:nuitka