154 lines
6.4 KiB
Docker
154 lines
6.4 KiB
Docker
# ============================================================
|
||
# 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"] |