feat: 新增 Python 3.14t 自由线程镜像 (#6434)

* fix(resource): select free-threaded extension ABI

* chore(deps): require moviepilot-rust 0.2.9

* perf: add free-threaded runtime comparison

* feat: add free-threaded runtime profile

* chore(deps): require moviepilot-rust 0.3.0

* test: isolate system endpoint import graph

* fix(docker): preserve runtime profile during recovery

* feat(runtime): expose active GIL state

* feat(plugin): log GIL fallback attribution

* test: refresh runtime observability dependency baseline

* fix(plugin): validate the active uv runtime profile

* test(runtime): expand free-threaded benchmark evidence

* docs(runtime): define v3t governance gates

* test(runtime): separate rust benchmark modes

* docs: sync free-threaded architecture baseline

* perf: add PostgreSQL driver comparison

* docs(runtime): record final free-threaded evidence

* fix(runtime): converge dual-profile dependency verification

* fix(runtime): scope Python 3.14 warning filter

* fix(runtime): match actual oss2 syntax warning

* docs(runtime): refresh free-threaded benchmark evidence

* test(architecture): refresh runtime dependency baseline

* ci: skip unused Trivy Java database

* build: exclude local verification artifacts

* docs(runtime): refresh PostgreSQL driver benchmarks

* docs(runtime): record plugin restore acceptance

* docs(runtime): record amd64 candidate acceptance

* ci: pin beta image publisher action

* test(architecture): merge runtime dependency baseline

* feat(runtime): expose Python GIL status

* docs(runtime): document Python runtime status fields
This commit is contained in:
InfinityPacer
2026-08-24 17:48:14 +08:00
committed by GitHub
parent 88dce4ca8e
commit 326b5cf3ad
63 changed files with 5294 additions and 253 deletions
+74 -11
View File
@@ -1,5 +1,8 @@
# syntax=docker/dockerfile:1
ARG MOVIEPILOT_PYTHON_VARIANT="standard"
ARG MOVIEPILOT_PYTHON_VERSION="3.14.7"
FROM ghcr.io/astral-sh/uv:0.12.5@sha256:e85be844203885286c60ffad8a858d48afb6c5a5c237ca0e67f12e74b8f174b1 AS uv
@@ -9,7 +12,10 @@ FROM rclone/rclone:1.75.0@sha256:b06aed988cf5967de7c25be5925240983981c757f4ed1ac
FROM mwader/static-ffmpeg:8.1.1@sha256:735f84b905e00d5c618b667f0b053f83b1096f5fc404c607e6134bf2275a0e0a AS ffmpeg
FROM python:3.14.7-slim-trixie AS base
FROM python:${MOVIEPILOT_PYTHON_VERSION}-slim-trixie AS base
FROM rust:slim-trixie AS rust_toolchain
# 准备外部制品所需的最小工具集
@@ -33,6 +39,7 @@ ENV LANG="C.UTF-8" \
PUID=0 \
PGID=0 \
UMASK=000 \
PYTHON_THREAD_INHERIT_CONTEXT=0 \
VENV_PATH="/opt/venv"
ENV PATH="${VENV_PATH}/bin:${PATH}"
@@ -94,8 +101,8 @@ RUN apt-get update \
/var/tmp/*
# 准备 python 环境
FROM base AS prepare_venv
# 准备 Python 环境的公共输入
FROM base AS prepare_venv_common
# 设置环境变量
ENV LANG="C.UTF-8" \
@@ -112,15 +119,65 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
jq \
wget
# 按锁文件创建主程序虚拟环境
WORKDIR /app
COPY --from=uv /uv /usr/local/bin/uv
COPY pyproject.toml uv.lock ./
RUN python3 -m venv --without-pip ${VENV_PATH} \
# 准备标准 Python 运行环境
FROM prepare_venv_common AS prepare_venv_standard
RUN mkdir -p /opt/python \
&& python3 -m venv --without-pip ${VENV_PATH} \
&& UV_PROJECT_ENVIRONMENT=${VENV_PATH} uv sync \
--locked \
--no-dev \
--no-install-project
--locked \
--no-default-groups \
--group runtime-standard \
--no-install-project
# free-threaded 原生依赖需要 Rust 和 C 构建工具链。
FROM prepare_venv_common AS prepare_venv_free-threaded
ARG MOVIEPILOT_PYTHON_VERSION
ENV CARGO_HOME="/usr/local/cargo" \
RUSTUP_HOME="/usr/local/rustup" \
UV_PYTHON_INSTALL_DIR="/opt/python"
ENV PATH="${CARGO_HOME}/bin:${VENV_PATH}/bin:${PATH}"
COPY --from=rust_toolchain /usr/local/cargo /usr/local/cargo
COPY --from=rust_toolchain /usr/local/rustup /usr/local/rustup
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& rm -rf /var/lib/apt/lists/* \
&& uv python install --no-bin "${MOVIEPILOT_PYTHON_VERSION}t" \
&& python_bin="$(uv python find --managed-python "${MOVIEPILOT_PYTHON_VERSION}t")" \
&& "${python_bin}" -m venv --without-pip ${VENV_PATH} \
&& UV_PROJECT_ENVIRONMENT=${VENV_PATH} uv sync \
--locked \
--no-default-groups \
--group runtime-free-threaded \
--no-install-project \
--python "${python_bin}"
FROM prepare_venv_standard AS verify_venv_standard
COPY app/doctor/dependencies.py /tmp/moviepilot-runtime-dependencies.py
RUN "${VENV_PATH}/bin/python" /tmp/moviepilot-runtime-dependencies.py --full
FROM prepare_venv_free-threaded AS verify_venv_free-threaded
COPY app/doctor/dependencies.py /tmp/moviepilot-runtime-dependencies.py
RUN "${VENV_PATH}/bin/python" /tmp/moviepilot-runtime-dependencies.py --full
ARG MOVIEPILOT_PYTHON_VARIANT
FROM verify_venv_${MOVIEPILOT_PYTHON_VARIANT} AS prepare_venv
# 准备后端源码
FROM base AS prepare_backend
@@ -184,10 +241,15 @@ FROM prepare_payload AS prepare_resources
ARG TARGETARCH
ARG MOVIEPILOT_RESOURCES_REF="main"
ARG MOVIEPILOT_PYTHON_VARIANT="standard"
RUN set -eu; \
test -n "${MOVIEPILOT_RESOURCES_REF}"; \
python_ver="$(python3 -c 'import sys; print(f"cpython-{sys.version_info.major}{sys.version_info.minor}")')"; \
case "${MOVIEPILOT_PYTHON_VARIANT}" in \
standard) python_ver="$(python3 -c 'import sys; print(f"cpython-{sys.version_info.major}{sys.version_info.minor}")')" ;; \
free-threaded) python_ver="cpython-314t" ;; \
*) printf 'Unsupported Python variant: %s\n' "${MOVIEPILOT_PYTHON_VARIANT}" >&2; exit 1 ;; \
esac; \
target_arch="${TARGETARCH:-$(uname -m)}"; \
case "${target_arch}" in \
arm64|aarch64) suffix="aarch64-linux-gnu" ;; \
@@ -230,6 +292,7 @@ COPY --from=rclone /usr/local/bin/rclone /usr/bin/rclone
# python 环境
COPY --from=prepare_venv --chmod=777 ${VENV_PATH} ${VENV_PATH}
COPY --from=prepare_venv /opt/python /opt/python
COPY --from=uv /uv /usr/local/bin/uv
# 浏览器运行依赖
@@ -252,8 +315,8 @@ COPY --from=prepare_control /bundle/bin/moviepilot /usr/local/bin/moviepilot
RUN mkdir -p ${HOME} \
&& groupadd -r moviepilot -g 918 \
&& useradd -r moviepilot -g moviepilot -d ${HOME} -s /bin/bash -u 918 \
&& python_ver=$(python3 -V | awk '{print $2}') \
&& echo "/app/" > ${VENV_PATH}/lib/python${python_ver%.*}/site-packages/app.pth \
&& site_packages="$(${VENV_PATH}/bin/python -c 'import sysconfig; print(sysconfig.get_path("purelib"))')" \
&& echo "/app/" > "${site_packages}/app.pth" \
&& echo 'fs.inotify.max_user_watches=5242880' >> /etc/sysctl.conf \
&& echo 'fs.inotify.max_user_instances=5242880' >> /etc/sysctl.conf \
&& echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen \