Files
DjangoAdmin_Django_EleVue/.jenkins/Dockerfile
T
2026-09-12 01:36:02 +08:00

199 lines
9.0 KiB
Docker
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# Dockerfile:多阶段构建 Python 应用镜像
#
# 构建思路:
# - builder 阶段:安装编译工具链,编译并安装 Python 依赖
# - runtime 阶段:只保留运行期必需内容,丢弃编译器
#
# 通过 --build-arg 动态注入以下变量,便于在 CI 中复用同一份 Dockerfile:
# VAR_BASE_IMAGE 基础镜像(如 python:3.12-slim、自定义的带 esxi 用户的镜像)
# VAR_PYTHON_PREFIX Python 安装前缀(依赖安装位置)
# VAR_JARFILE_PATH 项目源码目录(相对构建上下文)
# VAR_PROFILES 应用 profile(dev / prod ...)
# VAR_PORT 应用监听端口
# VAR_JARFILE 启动入口文件名(不含 .py)
# ============================================================
# ------------------------------------------------------------
# 声明构建参数
# 基础镜像用 ARG 而不是直接 FROM,方便 CI 动态切换
# Python 前缀单独抽出,避免在 COPY / pip --prefix 里重复硬编码
# ------------------------------------------------------------
ARG VAR_BASE_IMAGE
ARG VAR_PYTHON_PREFIX=/usr/local/python3.12.8
# ============================================================
# 阶段一:builder —— 编译并安装 Python 依赖
# ============================================================
FROM ${VAR_BASE_IMAGE} AS builder
# 基础镜像末尾可能设置了非 root 用户(如 esxi),
# 这里切回 root,否则 yum install 会因权限不足失败
USER root
# 镜像作者信息(仅元数据)
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 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=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 && \
yum install -y gcc gcc-c++ make cmake \
openssl-devel bzip2-devel libffi-devel \
mariadb-devel pkgconf-pkg-config && \
yum clean all && rm -rf /var/cache/yum
#RUN --mount=type=cache,target=/var/cache/dnf,sharing=locked,id=dnf-cache \
# dnf install -y yum-utils net-tools && \
# dnf install -y gcc gcc-c++ make cmake \
# openssl-devel bzip2-devel libffi-devel \
# mariadb-devel pkgconf-pkg-config
# ------------------------------------------------------------
# 配置 pip 国内镜像并升级 pip / setuptools / wheel
# 老版本的 pip 解析依赖容易出错,先升级到最新
# ------------------------------------------------------------
RUN pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple && \
pip3 config set install.trusted-host mirrors.aliyun.com && \
python3 -m pip install --upgrade pip setuptools wheel
# ------------------------------------------------------------
# 拷贝依赖清单
# 只拷贝 requirements.txt 而不是整个项目,
# 这样源码变化但 requirements 未变时可以复用 pip install 层缓存
# ------------------------------------------------------------
ARG VAR_JARFILE_PATH
WORKDIR /opt/apps
COPY ${VAR_JARFILE_PATH}/requirements.txt ./
# ------------------------------------------------------------
# 将依赖安装到 Python 的 prefix 下
# --prefix=${VAR_PYTHON_PREFIX} 与 runtime 阶段的拷贝路径保持一致
# python3 -m pip 确保使用同一个解释器
# uwsgi 生产环境 WSGI 服务器,单独安装
# 注意:末尾不要多写反斜杠,否则会把下一行注释拼进来导致语法错误
# ------------------------------------------------------------
RUN python3 -m pip install --prefix=${VAR_PYTHON_PREFIX} -r requirements.txt && \
python3 -m pip install --prefix=${VAR_PYTHON_PREFIX} uwsgi
# ============================================================
# 阶段二:runtime —— 只保留运行时内容
# ============================================================
FROM ${VAR_BASE_IMAGE} AS runtime
# 切回 root 以便 yum install / chown
USER root
# 镜像作者信息
LABEL MAINTAINER="djangoadmin@126.com"
# ------------------------------------------------------------
# 运行期环境变量
# PYTHONUNBUFFERED=1 日志实时输出,便于 docker logs 观察
# PYTHONDONTWRITEBYTECODE=1 不写 .pyc,避免容器内产生垃圾文件
# ------------------------------------------------------------
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
# ------------------------------------------------------------
# 运行期构建参数
# VAR_PYTHON_PREFIX Python 前缀(必须与 builder 保持一致)
# VAR_PROFILES 配置 profile(dev / prod)
# VAR_PORT 应用监听端口
# VAR_JARFILE 启动入口文件名(不含 .py)
# VAR_JARFILE_PATH 项目源码目录
# ------------------------------------------------------------
ARG VAR_PYTHON_PREFIX=/usr/local/python3.12.8
ARG VAR_PROFILES
ARG VAR_PORT
ARG VAR_JARFILE
ARG VAR_JARFILE_PATH
# ------------------------------------------------------------
# 将 ARG 转成 ENV,运行期可通过环境变量读取
# PORT 供 EXPOSE 与 CMD 使用
# PYFILE 入口文件名
# PROFILES 应用读取的 profile
# ------------------------------------------------------------
ENV PORT=${VAR_PORT} \
PYFILE=${VAR_JARFILE} \
PROFILES=${VAR_PROFILES}
# ------------------------------------------------------------
# 安装运行期依赖
# 只装运行库,不装 -devel 头文件,可显著减小镜像体积:
# net-tools netstat 等网络排查工具(如不需要可去掉)
# openssl-libs SSL 运行库(替代 openssl-devel)
# bzip2-libs bz2 运行库(替代 bzip2-devel)
# libffi ctypes 运行库(替代 libffi-devel)
# mysql-libs MySQL 客户端运行库(替代 mysql-devel)
# 注意:若应用运行期确实需要头文件(如运行期编译),再改回 -devel
# ------------------------------------------------------------
RUN yum install -y net-tools openssl-libs bzip2-libs libffi mysql-libs && \
yum clean all && rm -rf /var/cache/yum
# ------------------------------------------------------------
# 从 builder 拷贝已编译安装好的 Python 及依赖
# 源与目标都使用 ${VAR_PYTHON_PREFIX},保证 runtime 的 Python
# 能在自己的 site-packages 里找到 Django 等包
# ------------------------------------------------------------
COPY --from=builder ${VAR_PYTHON_PREFIX} ${VAR_PYTHON_PREFIX}
# ------------------------------------------------------------
# 工作区
# ------------------------------------------------------------
WORKDIR /opt/apps
# ------------------------------------------------------------
# 拷贝项目源码
# 建议配合 .dockerignore 排除 .git、__pycache__、本地虚拟环境等
# ------------------------------------------------------------
COPY ${VAR_JARFILE_PATH}/ ./
# ------------------------------------------------------------
# 一次性修正属主:
# /opt/apps 保证 esxi 可读写源码
# ${VAR_PYTHON_PREFIX} 保证 esxi 可访问 Python 及其 site-packages
# 合并成一条 RUN,减少镜像层
# ------------------------------------------------------------
RUN chown -R esxi:esxi /opt/apps ${VAR_PYTHON_PREFIX}
# ------------------------------------------------------------
# 切回非 root 用户运行应用(安全加固)
# ------------------------------------------------------------
USER esxi
# ------------------------------------------------------------
# 声明暴露端口(实际映射由 docker run -p 决定)
# ------------------------------------------------------------
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"]