Files
DjangoAdmin_FastAPI_EleVue/.jenkins/Dockerfile
T
2026-09-12 17:39:13 +08:00

142 lines
5.6 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-base:3.12.8(RockyLinux 8 + Python 3.12.8 + mariadb-connector-c)
#
# 设计要点
# - builder 只编译依赖,装到 /opt/deps,不碰基础镜像的 Python 目录
# - runtime 继承基础镜像的 Python,只把依赖的 site-packages COPY 过来
# - MySQL 运行库(mariadb-connector-c)由基础镜像预置,runtime 无需重复安装
# - 用 COPY --chown 指定属主,避免额外的 chown 层
# - 源码 COPY 放在依赖之后,保护依赖层缓存
#
# 构建参数
# VAR_BASE_IMAGE 基础镜像
# VAR_PYTHON_PREFIX Python 安装前缀(与基础镜像一致)
# VAR_PYTHON_SHORT_VERSION Python 主次版本号,用于 site-packages 路径
# VAR_PYFILE_PATH 项目源码目录
# VAR_PROFILES 应用 profile(dev / prod)
# VAR_PORT 应用监听端口
# VAR_PYFILE 入口文件名(不含 .py)
# ============================================================
# ------------------------------------------------------------
# 全局构建参数
# 在 FROM 之前声明,可供后续各阶段引用
# ------------------------------------------------------------
ARG VAR_BASE_IMAGE
ARG VAR_PYTHON_PREFIX=/usr/local/python3.12.8
ARG VAR_PYTHON_SHORT_VERSION=3.12
# ============================================================
# 阶段一:builder —— 编译并安装项目依赖
# ============================================================
FROM ${VAR_BASE_IMAGE} AS builder
# 阶段内重新声明,否则读不到全局 ARG
# Docker 规则:全局 ARG 只在 FROM 行可见,阶段内使用必须重新声明
ARG VAR_PYTHON_PREFIX
ARG VAR_PYTHON_SHORT_VERSION
ARG VAR_PYFILE_PATH
# 基础镜像末尾是 esxi 用户;dnf/pip 需要写系统目录和 /opt/deps,
# 所以这里仍需 root
USER root
LABEL MAINTAINER="djangoadmin@126.com"
# 编译阶段环境变量
# PYTHONUNBUFFERED=1 日志实时输出
# PYTHONDONTWRITEBYTECODE=1 不生成 .pyc
# PIP_NO_CACHE_DIR=1 不缓存 wheel
# PIP_DISABLE_PIP_VERSION_CHECK=1 关闭 pip 版本检查
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
# 安装编译工具链
# gcc / gcc-c++ / make 编译 C 扩展(mysqlclient、uwsgi 等)
# openssl-devel cryptography、_ssl 等
# bzip2-devel / libffi-devel
# mariadb-devel 编译 mysqlclient(提供 .pc 文件)
# pkgconf-pkg-config 提供 pkg-config 命令(mysqlclient 2.2.x 必需)
RUN set -eux; \
# 替换 dnf 源为阿里云镜像
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak /etc/yum.repos.d/*.repo; \
dnf install -y --setopt=install_weak_deps=False \
gcc gcc-c++ make \
openssl-devel bzip2-devel libffi-devel \
mariadb-devel pkgconf-pkg-config; \
dnf clean all; rm -rf /var/cache/dnf
# 配置 pip 国内镜像源(阿里云 PyPI)
RUN pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple && \
pip3 config set install.trusted-host mirrors.aliyun.com
# 只拷 requirements.txt
# 源码变化但依赖未变时,可复用 pip install 层缓存
WORKDIR /opt/apps
COPY ${VAR_PYFILE_PATH}/requirements.txt ./
# 依赖装到 /opt/deps,与基础镜像 Python 目录解耦
# --prefix=/opt/deps 安装到独立目录,runtime 只 COPY 这个目录的产物
# uwsgi 生产环境 WSGI 服务器,单独安装
RUN python3 -m pip install --prefix=/opt/deps -r requirements.txt && \
python3 -m pip install --prefix=/opt/deps uwsgi
# ============================================================
# 阶段二:runtime —— 最终业务镜像
# ============================================================
FROM ${VAR_BASE_IMAGE} AS runtime
# 阶段内重新声明
ARG VAR_PYTHON_PREFIX
ARG VAR_PYTHON_SHORT_VERSION
ARG VAR_PROFILES
ARG VAR_PORT
ARG VAR_PYFILE
ARG VAR_PYFILE_PATH
LABEL MAINTAINER="djangoadmin@126.com"
# 运行期环境变量
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1
# ARG 转 ENV,运行期可读取
# PORT 供 EXPOSE 与 CMD 使用
# PYFILE 入口文件名
# PROFILES 应用读取的 profile
ENV PORT=${VAR_PORT} \
PYFILE=${VAR_PYFILE} \
PROFILES=${VAR_PROFILES}
# 把 builder 编译好的 site-packages 和可执行文件拷到基础镜像 Python 对应目录
# 目标路径必须与基础镜像 Python 的实际 site-packages 一致
# 用 COPY --chown 指定属主,避免额外的 chown 层
COPY --chown=esxi:esxi --from=builder \
/opt/deps/lib/python${VAR_PYTHON_SHORT_VERSION}/site-packages/ \
${VAR_PYTHON_PREFIX}/lib/python${VAR_PYTHON_SHORT_VERSION}/site-packages/
COPY --chown=esxi:esxi --from=builder /opt/deps/bin/ ${VAR_PYTHON_PREFIX}/bin/
WORKDIR /opt/apps
# 拷项目源码(放在依赖之后,保护 pip 层缓存)
# 建议配合 .dockerignore 排除 .git、__pycache__、本地虚拟环境等
COPY --chown=esxi:esxi ${VAR_PYFILE_PATH}/ ./
USER esxi
EXPOSE ${PORT}
# 启动命令
# ${PYFILE} 为入口文件名(不含 .py),如 manage
# runserver 仅适合开发/调试;生产环境建议改用 uwsgi / gunicorn,例如:
# CMD ["sh","-c","uwsgi --http 0.0.0.0:${PORT} \
# --module 你的项目名.wsgi:application \
# --processes 4 --threads 2"]
CMD ["sh", "-c", "uvicorn src.main:app --host 0.0.0.0 --port ${PORT}"]