顾乔芝士网

持续更新的前后端开发技术栈

Dockerfile 修改为 Cython 编译成 .so 并打包运行的版本

基于 Cython 编译成 .so 模块,这样镜像里不会留下 .py 源文件,只保留编译后的二进制扩展。

假设你的入口是 main.py,项目结构是:

/app
  ├── main.py
  ├── other_module.py
  ├── requirements.txt

Dockerfile(Cython 编译版本)

# 使用 Python 3.12 作为基础镜像
FROM python:3.12-slim as builder

# 设置工作目录
WORKDIR /app

# 设置环境变量
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

# 安装系统依赖和构建工具
RUN apt-get update && apt-get install -y \
    gcc \
    default-libmysqlclient-dev \
    pkg-config \
    python3-dev \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# 复制 requirements.txt 并安装依赖(包含 cython)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt \
    && pip install cython setuptools wheel

# 复制源码
COPY . .

# 将所有 .py 源码编译为 .so,并删除 .py
RUN python -m compileall .
RUN find . -name "*.py" ! -name "setup.py" -type f -exec cythonize -3 -i {} \; \
    && find . -name "*.py" -type f -delete \
    && find . -name "*.c" -type f -delete

# ===============================
# 运行阶段镜像(更小,不含构建工具)
# ===============================
FROM python:3.12-slim

WORKDIR /app

# 仅复制依赖和编译好的代码
COPY --from=builder /usr/local /usr/local
COPY --from=builder /app /app

# 创建非 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 python -c "import pymysql; print('Health check passed')" || exit 1

# 启动应用(入口改成模块形式,调用编译好的 .so)
CMD ["python", "-m", "main"]

工作机制

  1. builder 阶段:
  2. 安装依赖和 Cython
  3. 把 .py 转换成 .so 文件
  4. 删除 .py、.c 文件 → 镜像中不再存在源码
  5. runtime 阶段:
  6. 只包含运行环境 + .so 文件
  7. 镜像更小、更安全

你接下来要做的

  • 构建镜像:
  • docker build -t myapp:cython .
  • 运行:
  • docker run --rm myapp:cython
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言