# ============================================================================
# 基础镜像构建文件：CentOS 8 + Python 3.12.8（多阶段、精简版）
# 作者：小蚂蚁云团队
# 说明：
#   采用「builder + runtime」两阶段构建：
#     - builder 阶段：安装编译工具链（含 make/cmake/mariadb-devel/sqlite-devel），
#                     编译 Python，并裁剪安装目录
#     - runtime 阶段：只拷贝编译好的 Python + 运行时库，不携带任何编译工具
#   最终镜像体积约为单阶段版本的 1/3。
#
#   注：CentOS 8 已于 2021-12-31 EOL，官方源已下线。
#       本脚本把 dnf 源切换到阿里云 rockylinux 镜像（与 CentOS 8 二进制兼容），
#       保证 dnf install 仍然可用。
# ============================================================================


# ============================================================================
# 阶段一：builder —— 只负责编译 Python，产物最终会被丢弃
# ============================================================================
FROM centos:8 AS builder

# ----------------------------------------------------------------------------
# 环境变量
#   PYTHON_VERSION : Python 版本号，便于统一引用
#   PYTHON_HOME    : Python 安装前缀目录（--prefix 使用）
#   LANG           : 编译期语言环境，避免 make/configure 中文乱码
# ----------------------------------------------------------------------------
ENV PYTHON_VERSION=3.12.8 \
    PYTHON_HOME=/usr/local/python3.12.8 \
    LANG=en_US.UTF-8

# ----------------------------------------------------------------------------
# 安装编译 Python 所需的工具链与依赖库
# 关键点：
#   1) CentOS 8 官方源已 EOL，切换到阿里云 rockylinux 镜像（二进制兼容）
#   2) --setopt=install_weak_deps=False 不安装弱依赖，减少包数量
#   3) 编译完成后立即 dnf clean all，清除缓存
#   4) 加入 make / cmake / mariadb-devel / sqlite-devel：
#        - make           : Python 自身编译必需
#        - cmake          : 第三方 C 扩展（如部分数据库/科学计算库）构建用
#        - mariadb-devel  : 提供 mysql.h / mysql_config，编译 MySQL C 扩展用
#                           （CentOS 8 里 mysql-devel 已被 mariadb-devel 取代）
#        - sqlite-devel   : Python _sqlite3 模块编译必需
#   5) 不装 kernel-devel（除非要编译内核模块）
# ----------------------------------------------------------------------------
RUN set -eux; \
    # 禁用 mirrorlist，启用 vault 归档源
    sed -i 's/^mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo; \
    sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo; \
    dnf install -y --setopt=install_weak_deps=False \
        make cmake gcc gcc-c++ \
        openssl-devel bzip2-devel libffi-devel \
        zlib-devel readline-devel sqlite-devel \
        mariadb-devel \
        xz tar findutils; \
    dnf clean all; rm -rf /var/cache/dnf

# ----------------------------------------------------------------------------
# 把 Python 源码包 ADD 进来
#   - ADD 会自动解压 .tar.xz
#   - 该 tar.xz 只存在于 builder 阶段，最终镜像不会包含它
#   - 前提：构建上下文里需要有 Python-3.12.8.tar.xz
# ----------------------------------------------------------------------------
ADD Python-3.12.8.tar.xz /tmp/

# ----------------------------------------------------------------------------
# 编译并安装 Python
# 关键点：
#   1) 去掉 --enable-optimizations（PGO 训练会导致编译时间从几分钟涨到 20~40 分钟）
#   2) --enable-shared 生成 libpython3.12.so，方便其他程序链接
#   3) --with-system-ffi 使用系统 libffi，避免自编译
#   4) --with-ensurepip=install 安装 pip
#   5) 安装完成后对 Python 目录做「瘦身」：
#        - 删除 test/idlelib/tkinter/turtledemo/lib2to3 等运行时用不到的模块
#        - 保留 ensurepip 与 site-packages，否则 pip 会被一并删除
#        - 删除静态库 .a、libtool 文件 .la、__pycache__、.pyc
#        - 对 .so 执行 strip，去掉调试符号
#   6) 最后删除源码目录，避免残留在 builder 层
# ----------------------------------------------------------------------------
RUN set -eux; \
    cd /tmp/Python-3.12.8; \
    ./configure \
        --prefix=${PYTHON_HOME} \
        --enable-shared \
        --with-system-ffi \
        --with-ensurepip=install; \
    make -j"$(nproc)"; \
    make install; \
    \
    # ---- 裁剪 Python 安装目录，去掉运行时不需要的内容 ----
    # 注意：不要删 ensurepip，也不要删 site-packages/*
    cd ${PYTHON_HOME}; \
    rm -rf lib/python3.12/test \
           lib/python3.12/idlelib \
           lib/python3.12/tkinter \
           lib/python3.12/turtledemo \
           lib/python3.12/lib2to3 \
           lib/python3.12/config-3.12-*; \
    # ---- 删除 Python 缓存文件 ----
    find ${PYTHON_HOME} -name '__pycache__' -type d -exec rm -rf {} + 2>/dev/null || true; \
    find ${PYTHON_HOME} -name '*.pyc' -delete; \
    # ---- 删除静态库和 libtool 文件 ----
    find ${PYTHON_HOME} -name '*.a' -delete; \
    find ${PYTHON_HOME} -name '*.la' -delete; \
    # ---- 剥离 .so 动态库的调试符号 ----
    find ${PYTHON_HOME}/bin ${PYTHON_HOME}/lib -type f -name '*.so*' \
        -exec strip --strip-unneeded {} + 2>/dev/null || true; \
    \
    # ---- 清理源码目录 ----
    cd /tmp; rm -rf /tmp/Python-3.12.8


# ============================================================================
# 阶段二：runtime —— 最终镜像
# 只包含：运行时依赖库 + 从 builder 拷贝过来的 Python
# ============================================================================
FROM centos:8 AS runtime

# ----------------------------------------------------------------------------
# 镜像元数据（LABEL 不影响镜像体积）
# ----------------------------------------------------------------------------
LABEL maintainer="小蚂蚁云团队" \
      version="2.1" \
      description="基于CentOS 8的Python 3.12.8精简运行环境（含 MySQL/SQLite 运行时库）" \
      python.version="3.12.8"

# ----------------------------------------------------------------------------
# 运行时环境变量
#   PYTHON_HOME : 与 builder 保持一致，便于 COPY 路径引用
#   TZ          : 时区
#   LANG        : 默认语言环境
#   PATH        : 把 Python 的 bin 目录放到最前，保证 python/pip 生效
# ----------------------------------------------------------------------------
ENV PYTHON_VERSION=3.12.8 \
    PYTHON_HOME=/usr/local/python3.12.8 \
    TZ=Asia/Shanghai \
    LANG=en_US.UTF-8 \
    PATH=/usr/local/python3.12.8/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# ----------------------------------------------------------------------------
# 安装运行时所需的系统库（注意：全部是运行时库，不是 -devel 开发包）
#   openssl-libs           : _ssl 模块依赖
#   bzip2-libs             : _bz2 模块依赖
#   libffi                 : _ctypes 模块依赖
#   zlib                   : zlib 模块依赖
#   readline               : 交互式命令行
#   sqlite-libs            : _sqlite3 模块依赖（对应 builder 的 sqlite-devel）
#   mariadb-connector-c    : MySQL/MariaDB 客户端运行库
#                            （对应 builder 的 mariadb-devel，
#                              编译出的 mysqlclient 等 C 扩展运行需要）
#   glibc-langpack-en      : en_US.UTF-8 locale
#   shadow-utils           : useradd/groupadd 等
#   tzdata                 : 时区数据
# 同时完成：时区、locale 配置
# ----------------------------------------------------------------------------
RUN set -eux; \
    # ---- 把 CentOS 8 官方源替换为阿里云 rockylinux 镜像 ----
    sed -e 's|^mirrorlist=|#mirrorlist=|g' \
        -e 's|^#baseurl=http://mirror.centos.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
        -i.bak /etc/yum.repos.d/CentOS-*.repo; \
    # ---- 安装运行时依赖 ----
    dnf install -y --setopt=install_weak_deps=False \
        openssl-libs \
        bzip2-libs \
        libffi \
        zlib \
        readline \
        sqlite-libs \
        mariadb-connector-c \
        glibc-langpack-en \
        shadow-utils \
        tzdata; \
    # ---- 清理缓存 ----
    dnf clean all; rm -rf /var/cache/dnf; \
    \
    # ---- 时区配置 ----
    ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime; \
    echo ${TZ} > /etc/timezone; \
    # ---- 语言环境配置 ----
    echo 'LANG="en_US.UTF-8"' > /etc/locale.conf; \
    echo 'LC_ALL="en_US.UTF-8"' >> /etc/locale.conf

# ----------------------------------------------------------------------------
# 从 builder 阶段拷贝编译好的 Python
#   - 只拷贝 ${PYTHON_HOME}，编译工具链完全不进入最终镜像
#   - 路径保持一致，避免 PATH 失效
# ----------------------------------------------------------------------------
COPY --from=builder ${PYTHON_HOME} ${PYTHON_HOME}

# ----------------------------------------------------------------------------
# 建立 python/pip 软链，并注册动态链接库
#   1) /usr/bin/python3、python、pip 指向 Python 安装目录
#   2) 把 ${PYTHON_HOME}/lib 写入 ld.so.conf.d 并执行 ldconfig
#      否则运行 python 时会报 "libpython3.12.so not found"
#   3) 最后验证 python3 / pip 是否可用
# ----------------------------------------------------------------------------
RUN set -eux; \
    ln -sf ${PYTHON_HOME}/bin/python3.12 /usr/bin/python3; \
    ln -sf ${PYTHON_HOME}/bin/python3.12 /usr/bin/python; \
    ln -sf ${PYTHON_HOME}/bin/pip3 /usr/bin/pip; \
    echo "${PYTHON_HOME}/lib" > /etc/ld.so.conf.d/python3.conf; \
    ldconfig; \
    python3 --version; pip --version

# ----------------------------------------------------------------------------
# 创建非 root 用户 esxi
#   1) groupadd -r  : 创建系统组
#   2) useradd -r   : 创建系统用户，家目录 /opt/apps
#   3) 把工作目录和 Python 目录的属主交给 esxi
# ----------------------------------------------------------------------------
RUN set -eux; \
    groupadd -r esxi; \
    useradd -r -g esxi -d /opt/apps -s /bin/bash esxi; \
    mkdir -p /opt/apps; \
    chown -R esxi:esxi /opt/apps ${PYTHON_HOME}

# ----------------------------------------------------------------------------
# 工作目录 & 运行用户
#   - WORKDIR 在 USER 之前设置，避免权限问题
#   - USER esxi 让容器以非 root 身份运行，提升安全性
# ----------------------------------------------------------------------------
WORKDIR /opt/apps
USER esxi

# ----------------------------------------------------------------------------
# 健康检查：每 30s 检查一次 python3 是否可用
# ----------------------------------------------------------------------------
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD python3 --version > /dev/null 2>&1 || exit 1

# ----------------------------------------------------------------------------
# 默认启动命令（可被子镜像或 docker run 覆盖）
# ----------------------------------------------------------------------------
CMD ["python3", "--version"]