From ca51c2f8c5f4c84ee7d3b41bfcff01b89a558821 Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Fri, 16 Jan 2026 12:40:56 +0800 Subject: [PATCH] Fix install plugin dependencies in docker container (#1017) --- Dockerfile | 16 +++++++++++----- backend/plugin/requirements.py | 10 ++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a2e07a9..1d654a9e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,24 +22,30 @@ ENV UV_COMPILE_BYTECODE=1 \ # Install dependencies with cache RUN --mount=type=cache,target=/root/.cache/uv \ - uv sync --frozen --no-default-groups --group server + --mount=type=bind,source=uv.lock,target=uv.lock \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + uv sync --locked --no-default-groups --group server --no-install-project # === Runtime base server image === -FROM python:3.10-slim AS base_server +FROM python:3.10-slim-bookworm AS base_server RUN sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources \ && apt-get update \ - && apt-get install -y --no-install-recommends supervisor \ + && apt-get install -y --no-install-recommends curl ca-certificates supervisor \ && rm -rf /var/lib/apt/lists/* +ADD https://astral.sh/uv/install.sh /uv-installer.sh + +RUN sh /uv-installer.sh && rm /uv-installer.sh + +ENV PATH="/root/.local/bin/:$PATH" + COPY --from=builder /fba /fba COPY --from=builder /usr/local /usr/local COPY deploy/backend/supervisor/supervisord.conf /etc/supervisor/supervisord.conf -WORKDIR /fba/backend - # === FastAPI server image === FROM base_server AS fba_server diff --git a/backend/plugin/requirements.py b/backend/plugin/requirements.py index adf1b6b8..a39437f0 100644 --- a/backend/plugin/requirements.py +++ b/backend/plugin/requirements.py @@ -1,5 +1,6 @@ import os import subprocess +import sys from importlib.metadata import PackageNotFoundError, distribution @@ -25,6 +26,11 @@ def get_plugins() -> list[str]: return _get_plugins() +def _is_in_virtualenv() -> bool: + """检测当前是否在虚拟环境中运行""" + return hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) + + def install_requirements(plugin: str | None) -> None: # noqa: C901 """ 安装插件依赖 @@ -56,6 +62,8 @@ def install_requirements(plugin: str | None) -> None: # noqa: C901 if missing_dependencies: try: pip_install = ['uv', 'pip', 'install', '-r', requirements_file] + if not _is_in_virtualenv(): + pip_install.append('--system') if settings.PLUGIN_PIP_CHINA: pip_install.extend(['-i', settings.PLUGIN_PIP_INDEX_URL]) @@ -91,6 +99,8 @@ def uninstall_requirements(plugin: str) -> None: if os.path.exists(requirements_file): try: pip_uninstall = ['uv', 'pip', 'uninstall', '-r', str(requirements_file), '-y'] + if not _is_in_virtualenv(): + pip_uninstall.append('--system') subprocess.check_call(pip_uninstall, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) except subprocess.CalledProcessError as e: raise PluginInstallError(f'插件 {plugin} 依赖卸载失败:{e}') from e