diff --git a/Dockerfile b/Dockerfile index 6665c19..56d72ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,20 @@ RUN pnpm install --frozen-lockfile || pnpm install COPY frontend/ ./ RUN pnpm build +# === Stage 1b: stock-sdk 插件依赖 === +# stock-sdk 是 Node 型插件, Python 后端通过 subprocess 调 node bridge.mjs 抓数据。 +# 运行时镜像(python:3.11-slim)无 node, 也不应要求用户进容器手动 npm install +# (容器删除即丢失)。这里在构建期把依赖装好, 供 Stage 2 整体 COPY 过去。 +# 必须用 bookworm 系: 与 python:3.11-slim 同 debian 代次, 避免跨代次 libc 不匹配。 +FROM node:20-bookworm-slim AS stocksdk-builder +ARG USE_CN_MIRROR=1 +ARG NPM_REGISTRY=https://registry.npmmirror.com +WORKDIR /build +RUN if [ "$USE_CN_MIRROR" = "1" ]; then npm config set registry "$NPM_REGISTRY"; fi +COPY backend/app/plugins/stocksdk/package.json backend/app/plugins/stocksdk/package-lock.json ./ +# stock-sdk 是纯 JS 单包(无原生依赖), npm ci 精确还原 lockfile; 失败再退 install。 +RUN npm ci || npm install + # === Stage 2: Python 运行时 === FROM python:3.11-slim AS runtime ARG USE_CN_MIRROR=1 @@ -32,6 +46,15 @@ ARG PYPI_FALLBACK=https://mirrors.aliyun.com/pypi/simple ARG BACKEND_EXTRAS= WORKDIR /app +# Node.js 运行时: 供 stock-sdk 插件(node bridge.mjs)使用。 +# bookworm 自带 nodejs 18.19, 满足插件 engines>=18; --no-install-recommends 精简, +# 自带 libnode/libc-ares 等全部动态依赖, 无需手动补库。 +# 国内构建走 apt mirror 已在 debian 镜像sources.list 配好, 无需额外换源。 +RUN apt-get update \ + && apt-get install -y --no-install-recommends nodejs \ + && rm -rf /var/lib/apt/lists/* \ + && node --version + # 安装 uv(快) —— 国内镜像下三重兜底:主源 → 备用源 → 官方源, # 任一成功即可,避免单一镜像同步延迟/故障导致构建失败。 # uv 发版极频繁,国内镜像同步存在时间窗口,不锁版本且无 fallback 时 @@ -63,6 +86,10 @@ RUN if [ "$USE_CN_MIRROR" = "1" ]; then \ # (/backend/app/) 推导的, 容器内会错算到 /。这里用环境变量显式指定 # 三个关键路径, 确保 static / tiers / data 都指向容器内正确位置。 COPY backend/app ./app +# stock-sdk 插件依赖: 从 stocksdk-builder 整体拷入, 落点与 bridge.mjs 同目录 +# (/app/app/plugins/stocksdk/node_modules), 命中 bridge.mjs loadSDK() 第一候选路径。 +# COPY --from 不受 .dockerignore 的 **/node_modules 规则影响。 +COPY --from=stocksdk-builder /build/node_modules ./app/plugins/stocksdk/node_modules COPY tiers.yaml /app/tiers.yaml ENV STATIC_DIR=/app/static \ TIERS_YAML=/app/tiers.yaml \ diff --git a/README.md b/README.md index f12be97..4bd647c 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,8 @@ docker compose up --build # 打开 http://localhost:3018 ``` +镜像已内置 **stock-sdk** 数据源插件(Node 运行时 + 依赖),开箱即用。 + > 📖 Docker 进阶、GitHub Actions 自构建、老 CPU 兼容、访问密码设置等见 [docs/deployment.md](./docs/deployment.md)。 ### 跑起来后的第一次使用 diff --git a/backend/app/plugins/stocksdk/plugin.yaml b/backend/app/plugins/stocksdk/plugin.yaml index 9aa4eea..1c8eeab 100644 --- a/backend/app/plugins/stocksdk/plugin.yaml +++ b/backend/app/plugins/stocksdk/plugin.yaml @@ -1,6 +1,7 @@ # stock-sdk 内置可选数据源插件 # 基于 stock-sdk (Node.js) 的免费 A 股行情, 无需 API Key。 -# 用户需手动安装依赖后才可用: cd backend/app/plugins/stocksdk && npm install +# Docker 部署已内置 Node 运行时与本插件依赖, 开箱即用; +# 开发模式下需手动安装依赖: cd backend/app/plugins/stocksdk && npm install name: stocksdk display_name: "stock-sdk(免费行情)" @@ -9,4 +10,4 @@ entry: app.plugins.stocksdk.provider:StockSDKProvider check: app.plugins.stocksdk.bridge:availability datasets: [daily, adj_factor, minute, realtime] description: "基于 stock-sdk 的免费 A 股行情, 无需 API Key。日K/除权/分钟/实时全市场。需运行环境含 Node.js 18+。" -install_hint: "cd backend/app/plugins/stocksdk && npm install" +install_hint: "cd backend/app/plugins/stocksdk && npm install(开发模式;Docker 部署已内置)" diff --git a/docs/deployment.md b/docs/deployment.md index ae9ca6b..e831cd3 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -45,6 +45,8 @@ docker compose up --build Docker 采用两阶段构建,前端 dist 拷进后端镜像,**单容器**运行,数据完全在自己手里。 +> 💡 镜像已内置 Node.js 运行时并预装 **stock-sdk** 插件依赖,Docker 部署下开箱即用,无需手动 `npm install`。 + 更新到新版本: ```bash diff --git a/docs/plugin-development.md b/docs/plugin-development.md index e8bf653..7148c41 100644 --- a/docs/plugin-development.md +++ b/docs/plugin-development.md @@ -1,7 +1,9 @@ # 数据源插件开发指南 数据源插件是可选的行情数据来源(stock-sdk、akshare 等),作为独立模块放在 -`backend/app/plugins/` 下。用户**手动安装依赖**后才可用;不安装完全不影响主功能。 +`backend/app/plugins/` 下。用户**手动安装依赖**后才可用(开发模式);不安装完全不影响主功能。 + +> 💡 **Docker 部署已预装**:内置插件(如 stock-sdk)的 Node 运行时与 `node_modules` 已在镜像构建期装好,Docker 下无需手动 `npm install`,开箱即用。下方"手动安装依赖"仅适用于开发模式。 ## 快速上手 @@ -32,7 +34,9 @@ install_hint: "pip install xxx" # 未装依赖时显示的安装提示 | runtime | 含义 | 典型场景 | |---|---|---| | `python` | 纯 Python 依赖, `pip install` | akshare、tushare | -| `node` | 需要 Node.js 运行时, `npm install` | stock-sdk | +| `node` | 需要 Node.js 运行时, `npm install` | stock-sdk(已内置,见下) | + +> stock-sdk 在 Docker 镜像里已预装 Node 运行时与依赖;开发模式下才需手动 `npm install`。 | `none` | 无额外依赖 | 纯 HTTP API 源 | `runtime` 字段当前仅用于 UI 展示, 实际依赖检测由 `check` 函数负责。