mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-02 21:34:32 +08:00
build(docker): decouple browser system deps from the venv layer
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
InfinityPacer
parent
80def953b5
commit
a76fc9f579
@@ -112,6 +112,46 @@ RUN apt-get update \
|
||||
/var/tmp/*
|
||||
|
||||
|
||||
# 从锁文件提取浏览器系统依赖所需的 Playwright 版本与哈希。
|
||||
# 本阶段随 uv.lock 每次变化重跑,但输出只含 Playwright 一行;BuildKit 按内容缓存后续 COPY,
|
||||
# 因此只有 Playwright 版本变化才会让浏览器依赖层失效,其他依赖变化不再迫使用户重新下载该层。
|
||||
FROM base AS prepare_playwright_requirement
|
||||
|
||||
COPY uv.lock /tmp/uv.lock
|
||||
RUN python3 -c "import tomllib; \
|
||||
packages = [item for item in tomllib.load(open('/tmp/uv.lock', 'rb'))['package'] if item['name'] == 'playwright']; \
|
||||
assert len(packages) == 1, 'uv.lock 必须且只能锁定一个 Playwright 版本'; \
|
||||
package = packages[0]; \
|
||||
hashes = sorted({item['hash'] for item in package.get('wheels', [])}); \
|
||||
assert hashes, 'uv.lock 缺少 Playwright wheel 哈希'; \
|
||||
open('/playwright-requirement.txt', 'w').write('playwright==' + package['version'] + ' ' + ' '.join('--hash=' + item for item in hashes) + '\\n')" \
|
||||
&& cat /playwright-requirement.txt
|
||||
|
||||
|
||||
# 浏览器运行依赖:只依赖系统软件包层和锁定的 Playwright 版本,不依赖虚拟环境内容。
|
||||
# Playwright 只装进临时目录读取依赖清单并执行 apt 安装,随后删除,不进入最终镜像。
|
||||
# 禁止写字节码,避免临时 pip 进程把系统 Python 标准库的 .pyc 留在该层。
|
||||
FROM prepare_package AS prepare_browser_deps
|
||||
|
||||
COPY --from=prepare_playwright_requirement /playwright-requirement.txt /tmp/playwright-requirement.txt
|
||||
RUN export PYTHONDONTWRITEBYTECODE=1 \
|
||||
&& python3 -m venv /tmp/playwright-cli \
|
||||
&& /tmp/playwright-cli/bin/pip install \
|
||||
--disable-pip-version-check \
|
||||
--no-cache-dir \
|
||||
--no-deps \
|
||||
--require-hashes \
|
||||
--only-binary :all: \
|
||||
-r /tmp/playwright-requirement.txt \
|
||||
&& /tmp/playwright-cli/bin/python -m playwright install-deps chromium \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
|
||||
|
||||
# 准备 Python 环境的公共输入
|
||||
FROM base AS prepare_venv_common
|
||||
|
||||
@@ -295,7 +335,7 @@ RUN mkdir -p \
|
||||
&& chmod 500 /bundle/rootfs/usr/local/lib/moviepilot/control/*.sh
|
||||
|
||||
# final 阶段安装运行时依赖并配置最终镜像
|
||||
FROM prepare_package AS final
|
||||
FROM prepare_browser_deps AS final
|
||||
|
||||
# jemalloc 默认按 CPU 数×4 建 arena,空闲 arena 的脏页会长期计入 RSS。脏页按 5 秒衰减归还
|
||||
# (muzzy 直接归还,避免 MADV_FREE 页继续计入 RSS);arena 限制为 8 个,带 GIL 的 Python 大块分配竞争很小。
|
||||
@@ -314,15 +354,6 @@ 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
|
||||
|
||||
# 浏览器运行依赖
|
||||
RUN playwright install-deps chromium \
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean \
|
||||
&& rm -rf \
|
||||
/tmp/* \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/tmp/*
|
||||
|
||||
# 准备容器控制面和运行目录
|
||||
COPY --link --from=prepare_control /bundle/rootfs/ /
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ def test_dockerfile_assigns_each_payload_to_an_independent_stage() -> None:
|
||||
):
|
||||
assert f" AS {stage}" in dockerfile
|
||||
|
||||
final_start = dockerfile.index("FROM prepare_package AS final")
|
||||
final_start = dockerfile.index("FROM prepare_browser_deps AS final")
|
||||
final = dockerfile[final_start:]
|
||||
copies = (
|
||||
"COPY --link --from=prepare_frontend /public /public",
|
||||
|
||||
@@ -130,7 +130,8 @@ def test_base_image_uses_refreshable_tag_and_apt_does_not_upgrade_in_place() ->
|
||||
assert "apt-get upgrade" not in dockerfile
|
||||
assert "pip uninstall" not in dockerfile
|
||||
assert "break-system-packages" not in dockerfile
|
||||
browser_install = dockerfile.split("RUN playwright install-deps chromium", maxsplit=1)[1]
|
||||
browser_install = dockerfile.split("python -m playwright install-deps chromium", maxsplit=1)[1]
|
||||
browser_install = browser_install.split("\nFROM ", maxsplit=1)[0]
|
||||
assert "apt-get install" not in browser_install
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user