更新Dockerfile

This commit is contained in:
2026-09-11 14:44:43 +08:00
parent 787fd670f1
commit 6a8a5891bf
+97 -5
View File
@@ -1,75 +1,167 @@
# ============================================================ # ============================================================
# 基础镜像参数 # 基础镜像参数
# ============================================================ # ============================================================
# VAR_BASE_IMAGE 通过 docker build --build-arg 传入,
# 例如:--build-arg VAR_BASE_IMAGE=python:3.12-slim
# 用 ARG 而不是直接 FROM xxx,方便在 CI 中动态切换基础镜像
ARG VAR_BASE_IMAGE ARG VAR_BASE_IMAGE
# ============================================================ # ============================================================
# 阶段一:builder —— 负责编译依赖 # 阶段一:builder —— 负责编译依赖
# 说明:
# - 这一阶段会安装 gcc/make/cmake 等编译工具
# - 编译好的 Python 依赖会安装到 /install 前缀
# - 最终该阶段整体被丢弃,编译工具不会进入 runtime 镜像
# ============================================================ # ============================================================
FROM ${VAR_BASE_IMAGE} AS builder FROM ${VAR_BASE_IMAGE} AS builder
# 镜像作者信息(仅元数据,不影响体积)
LABEL MAINTAINER="djangoadmin@126.com" LABEL MAINTAINER="djangoadmin@126.com"
# ------------------------------------------------------------
# 编译阶段的环境变量
# PYTHONUNBUFFERED=1 : Python 输出不缓冲,日志实时可见
# PYTHONDONTWRITEBYTECODE=1 : 不生成 .pyc,避免污染构建产物
# PIP_NO_CACHE_DIR=1 : pip 不缓存 wheel,减小体积
# PIP_DISABLE_PIP_VERSION_CHECK=1 : 关闭 pip 版本检查,加快安装
# ------------------------------------------------------------
ENV PYTHONUNBUFFERED=1 \ ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \ PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \ PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_DISABLE_PIP_VERSION_CHECK=1
# ------------------------------------------------------------
# 安装编译所需工具链 # 安装编译所需工具链
# yum-utils / net-tools : 系统工具
# gcc / gcc-c++ : C/C++ 编译器,编译 C 扩展必需
# make / cmake : 构建工具
# openssl-devel : 编译 _ssl / cryptography 相关依赖
# bzip2-devel : 编译 _bz2 模块
# libffi-devel : 编译 _ctypes 模块
# mysql-devel : 编译 mysqlclient 等 MySQL 驱动
# 末尾清理 yum 缓存,避免缓存被打进镜像层
# ------------------------------------------------------------
RUN yum install -y yum-utils net-tools && \ RUN yum install -y yum-utils net-tools && \
yum install -y gcc gcc-c++ make cmake \ yum install -y gcc gcc-c++ make cmake \
openssl-devel bzip2-devel libffi-devel mysql-devel && \ openssl-devel bzip2-devel libffi-devel mysql-devel && \
yum clean all && rm -rf /var/cache/yum yum clean all && rm -rf /var/cache/yum
# 配置 pip 国内镜像源 # ------------------------------------------------------------
# 配置 pip 国内镜像源并升级 pip
# - global.index-url : 指定阿里云 PyPI 镜像
# - install.trusted-host : 允许 http 源的 host
# - 升级 pip / setuptools / wheel,避免老版本解析依赖出错
# ------------------------------------------------------------
RUN pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple && \ RUN pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple && \
pip3 config set install.trusted-host mirrors.aliyun.com && \ pip3 config set install.trusted-host mirrors.aliyun.com && \
python3 -m pip install --upgrade pip setuptools wheel python3 -m pip install --upgrade pip setuptools wheel
# ------------------------------------------------------------
# 拷贝依赖清单 # 拷贝依赖清单
# VAR_PYFILE_PATH 由 --build-arg 传入,指向项目目录
# 这里只拷贝 requirements.txt,而不是整个项目目录,
# 目的是:当项目源码变化但 requirements.txt 未变时,
# 可以复用 pip install 这一层的缓存,加快构建
# ------------------------------------------------------------
ARG VAR_PYFILE_PATH ARG VAR_PYFILE_PATH
WORKDIR /opt/apps WORKDIR /opt/apps
COPY ${VAR_PYFILE_PATH}/requirements.txt ./ COPY ${VAR_PYFILE_PATH}/requirements.txt ./
# 将依赖安装到 /install 前缀,便于后续拷贝 # ------------------------------------------------------------
# 将依赖安装到 /install 前缀,便于后续整体拷贝到 runtime
# --prefix=/install : 依赖会被装到 /install/lib/pythonX.Y/site-packages
# uwsgi 单独安装(生产环境 WSGI 服务器)
# ------------------------------------------------------------
RUN pip3 install --prefix=/install -r requirements.txt && \ RUN pip3 install --prefix=/install -r requirements.txt && \
pip3 install --prefix=/install uwsgi pip3 install --prefix=/install uwsgi
# ============================================================ # ============================================================
# 阶段二:runtime —— 只保留运行时内容 # 阶段二:runtime —— 只保留运行时内容
# 说明:
# - 不再安装 gcc/make/cmake 等编译工具
# - 只装运行时需要的动态库
# - 从 builder 拷贝编译好的依赖
# ============================================================ # ============================================================
FROM ${VAR_BASE_IMAGE} AS runtime FROM ${VAR_BASE_IMAGE} AS runtime
# 镜像作者信息
LABEL MAINTAINER="djangoadmin@126.com" LABEL MAINTAINER="djangoadmin@126.com"
# ------------------------------------------------------------
# 运行时环境变量
# PYTHONUNBUFFERED=1 : 日志实时输出,便于 docker logs 观察
# PYTHONDONTWRITEBYTECODE=1 : 不写 .pyc,避免容器内产生垃圾文件
# ------------------------------------------------------------
ENV PYTHONUNBUFFERED=1 \ ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 PYTHONDONTWRITEBYTECODE=1
# 运行期参数 # ------------------------------------------------------------
# 运行期参数(由 --build-arg 传入)
# VAR_PROFILES : 配置 profile(如 dev / prod)
# VAR_PORT : 应用监听端口
# VAR_PYFILE : 启动入口文件名(不含 .py)
# VAR_PYFILE_PATH : 项目源码目录
# ------------------------------------------------------------
ARG VAR_PROFILES ARG VAR_PROFILES
ARG VAR_PORT ARG VAR_PORT
ARG VAR_PYFILE ARG VAR_PYFILE
ARG VAR_PYFILE_PATH ARG VAR_PYFILE_PATH
# ------------------------------------------------------------
# 把 ARG 转成 ENV,这样在容器运行期也能读取到这些变量
# PORT : 供 EXPOSE 和 CMD 使用
# PYFILE : 入口文件名
# PROFILES : 应用读取的 profile
# ------------------------------------------------------------
ENV PORT=${VAR_PORT} \ ENV PORT=${VAR_PORT} \
PYFILE=${VAR_PYFILE} \ PYFILE=${VAR_PYFILE} \
PROFILES=${VAR_PROFILES} PROFILES=${VAR_PROFILES}
# ------------------------------------------------------------
# 只安装运行期需要的动态库(不再需要 gcc/make/cmake 等) # 只安装运行期需要的动态库(不再需要 gcc/make/cmake 等)
# net-tools : netstat 等网络排查工具
# openssl-devel : 若应用运行期需要 SSL 头文件可保留;
# 若纯粹运行,可改为 openssl-libs 更省体积
# bzip2-devel : 同上,运行期一般只需 bzip2-libs
# libffi-devel : 运行期一般只需 libffi
# mysql-devel : 运行期一般只需 mysql-libs
# 提示:如果确定运行时不需要 -devel 头文件,可替换为对应的 -libs 包,
# 可进一步减小镜像体积
# ------------------------------------------------------------
RUN yum install -y net-tools openssl-devel bzip2-devel libffi-devel mysql-devel && \ RUN yum install -y net-tools openssl-devel bzip2-devel libffi-devel mysql-devel && \
yum clean all && rm -rf /var/cache/yum yum clean all && rm -rf /var/cache/yum
# ------------------------------------------------------------
# 从 builder 阶段拷贝已编译好的 Python 依赖 # 从 builder 阶段拷贝已编译好的 Python 依赖
# /install 下的内容会被合并到 /usr/local
# 这样 pip 安装的包就能被 runtime 阶段的 python 找到
# ------------------------------------------------------------
COPY --from=builder /install /usr/local COPY --from=builder /install /usr/local
# ------------------------------------------------------------
# 创建工作区 # 创建工作区
# ------------------------------------------------------------
WORKDIR /opt/apps WORKDIR /opt/apps
# ------------------------------------------------------------
# 拷贝项目源码 # 拷贝项目源码
# 注意:这里会把 VAR_PYFILE_PATH 目录下所有内容拷进 /opt/apps
# 建议配合 .dockerignore 排除 .git、__pycache__、本地虚拟环境等
# ------------------------------------------------------------
COPY ${VAR_PYFILE_PATH}/ ./ COPY ${VAR_PYFILE_PATH}/ ./
# 暴露端口 # ------------------------------------------------------------
# 暴露端口(仅声明,实际映射由 docker run -p 决定)
# ------------------------------------------------------------
EXPOSE ${PORT} EXPOSE ${PORT}
# 启动 # ------------------------------------------------------------
# 启动命令
# 使用 sh -c 以便解析 ${PYFILE}、${PORT} 环境变量
# 注意:runserver 仅适合开发/调试;
# 生产环境建议改为 uwsgi / gunicorn,例如:
# CMD ["sh","-c","uwsgi --http 0.0.0.0:${PORT} \
# --module ${PYFILE}.wsgi:application \
# --processes 4 --threads 2"]
# ------------------------------------------------------------
CMD ["sh", "-c", "python3 ${PYFILE}.py runserver 0.0.0.0:${PORT} --noreload"] CMD ["sh", "-c", "python3 ${PYFILE}.py runserver 0.0.0.0:${PORT} --noreload"]