# ============================================================ # Dockerfile:单阶段构建 Python 应用镜像(RockyLinux 8 + Python 3.12.8) # # 设计思路: # - 单阶段构建,所有依赖一次装齐,避免多阶段"包找不到/库缺失"问题 # - 编译工具链和运行库都保留在最终镜像里,换取构建稳定性和排错简单 # - 通过 --build-arg 动态注入变量,便于 CI 复用同一份 Dockerfile # # 构建参数说明: # VAR_BASE_IMAGE 基础镜像(RockyLinux 8 + Python 3.12.8 + esxi 用户) # VAR_PROFILES 应用 profile(dev / prod) # VAR_PORT 应用监听端口 # VAR_PYFILE 启动入口文件名(不含 .py),如 manage # VAR_PYFILE_PATH 项目源码目录(相对构建上下文) # ============================================================ # ------------------------------------------------------------ # 声明构建参数 # ------------------------------------------------------------ ARG VAR_BASE_IMAGE # ------------------------------------------------------------ # 基础镜像 # ------------------------------------------------------------ FROM ${VAR_BASE_IMAGE} # 镜像作者信息 LABEL MAINTAINER="djangoadmin@163.com" # ------------------------------------------------------------ # 切回 root # 基础镜像末尾通常设置了非 root 用户(如 esxi), # 不切回 root,后面的 dnf install / mkdir / chown 都会因权限不足失败 # ------------------------------------------------------------ USER root # ------------------------------------------------------------ # Python 运行期环境变量 # PYTHONUNBUFFERED=1 Python 输出不缓冲,日志实时可见 # PYTHONDONTWRITEBYTECODE=1 不生成 .pyc,避免容器内产生垃圾文件 # ------------------------------------------------------------ ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 # ------------------------------------------------------------ # 声明运行期构建参数 # ------------------------------------------------------------ ARG VAR_PROFILES ARG VAR_PORT ARG VAR_PYFILE ARG VAR_PYFILE_PATH # ------------------------------------------------------------ # 将 ARG 转为 ENV,运行期可通过环境变量读取 # ------------------------------------------------------------ ENV PORT=${VAR_PORT} \ PYFILE=${VAR_PYFILE} \ PROFILES=${VAR_PROFILES} # ------------------------------------------------------------ # 安装系统依赖(dnf 源换成国内镜像) # # RockyLinux 8 官方源可用,但换阿里云镜像更快: # baseurl=https://mirrors.aliyun.com/rockylinux # # 编译期工具: # gcc / gcc-c++ C/C++ 编译器 # make / cmake 构建工具 # openssl-devel 编译 _ssl / cryptography # bzip2-devel 编译 _bz2 # libffi-devel 编译 _ctypes # mariadb-devel 编译 mysqlclient(提供 .pc 文件) # pkgconf-pkg-config 提供 pkg-config 命令(mysqlclient 2.2.x 必需) # # 运行期库: # net-tools netstat 等网络排查工具 # openssl-libs SSL 运行库 # bzip2-libs bz2 运行库 # libffi ctypes 运行库 # mariadb-connector-c MySQL/MariaDB 客户端运行库 # # 注意: # 1) RockyLinux 8 里 MySQL 实际由 MariaDB 提供, # 运行库包名为 mariadb-connector-c(不是 mysql-libs) # 2) mariadb-devel 和 mysql-devel 不要同时安装,会冲突 # 3) 末尾清理 dnf 缓存,避免缓存进入镜像层 # ------------------------------------------------------------ RUN set -eux; \ # ---- 把 RockyLinux 8 官方源替换为阿里云镜像 ---- 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 \ yum-utils net-tools \ gcc gcc-c++ make cmake \ openssl-devel bzip2-devel libffi-devel \ mariadb-devel pkgconf-pkg-config \ openssl-libs bzip2-libs libffi mariadb-connector-c; \ # ---- 清理 dnf 缓存,减小镜像体积 ---- 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 # ------------------------------------------------------------ # 升级 pip / setuptools / wheel # --no-cache-dir 避免 pip 缓存进入镜像层 # ------------------------------------------------------------ RUN python3 -m pip install --upgrade --no-cache-dir pip setuptools wheel # ------------------------------------------------------------ # 创建工作区 # ------------------------------------------------------------ RUN mkdir -p /opt/apps WORKDIR /opt/apps # ------------------------------------------------------------ # 拷贝项目源码 # ------------------------------------------------------------ COPY ${VAR_PYFILE_PATH}/ ./ # ------------------------------------------------------------ # 安装 Python 依赖 # -r requirements.txt 项目依赖 # uwsgi 生产环境 WSGI 服务器 # ------------------------------------------------------------ RUN python3 -m pip install --no-cache-dir -r requirements.txt && \ python3 -m pip install --no-cache-dir uwsgi # ------------------------------------------------------------ # 修正属主 # ------------------------------------------------------------ RUN chown -R esxi:esxi /opt/apps # ------------------------------------------------------------ # 切回非 root 用户运行应用 # ------------------------------------------------------------ USER esxi # ------------------------------------------------------------ # 声明暴露端口 # ------------------------------------------------------------ EXPOSE ${PORT} # ------------------------------------------------------------ # 启动命令 # ${PYFILE} 为入口文件名(不含 .py),如 manage # 生产环境建议改用 uwsgi # ------------------------------------------------------------ CMD ["sh", "-c", "python3 ${PYFILE}.py runserver 0.0.0.0:${PORT} --noreload"]