mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 16:44:15 +08:00
fix legacy CPU Docker deployment
This commit is contained in:
@@ -14,5 +14,9 @@ HOST=0.0.0.0
|
||||
PORT=3018
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# Optional Docker build extras. Set to legacy-cpu on older VPS hosts
|
||||
# without AVX2/FMA support.
|
||||
BACKEND_EXTRAS=
|
||||
|
||||
# ===== Data =====
|
||||
DATA_DIR=./data
|
||||
|
||||
+7
-1
@@ -3,6 +3,7 @@
|
||||
ARG USE_CN_MIRROR=1
|
||||
ARG NPM_REGISTRY=https://registry.npmmirror.com
|
||||
ARG PYPI_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
ARG BACKEND_EXTRAS=
|
||||
|
||||
# === Stage 1: 前端构建 ===
|
||||
FROM node:20-alpine AS frontend-builder
|
||||
@@ -25,6 +26,7 @@ RUN pnpm build
|
||||
FROM python:3.11-slim AS runtime
|
||||
ARG USE_CN_MIRROR=1
|
||||
ARG PYPI_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
ARG BACKEND_EXTRAS=
|
||||
WORKDIR /app
|
||||
|
||||
# 安装 uv(快)
|
||||
@@ -38,7 +40,11 @@ RUN if [ "$USE_CN_MIRROR" = "1" ]; then \
|
||||
COPY README.md /README.md
|
||||
COPY backend/pyproject.toml backend/uv.lock* ./
|
||||
RUN if [ "$USE_CN_MIRROR" = "1" ]; then export UV_DEFAULT_INDEX="$PYPI_INDEX"; fi; \
|
||||
uv sync --frozen --no-dev || uv sync --no-dev
|
||||
set -- --no-dev; \
|
||||
for extra in $BACKEND_EXTRAS; do \
|
||||
set -- "$@" --extra "$extra"; \
|
||||
done; \
|
||||
uv sync --frozen "$@" || uv sync "$@"
|
||||
|
||||
# Backend code
|
||||
# 注意:Docker 里 WORKDIR=/app, 而 config.py 的 _PROJECT_ROOT 是按开发布局
|
||||
|
||||
@@ -192,6 +192,21 @@ docker compose up --build
|
||||
# 打开 http://localhost:3018
|
||||
```
|
||||
|
||||
如果你的 VPS / 物理机 CPU 较老,`docker compose up --build` 时出现类似
|
||||
`Missing required CPU features: avx2, fma, bmi1...` 或容器 `exit code 132`,
|
||||
先在 `.env` 里打开 Polars 兼容运行时再重建:
|
||||
|
||||
```ini
|
||||
BACKEND_EXTRAS=legacy-cpu
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
`legacy-cpu` 会让后端安装 `polars[rtcompat]`,适用于不支持 AVX2/FMA 的老 CPU;
|
||||
默认留空则保持 Polars 高性能运行时。
|
||||
|
||||
|
||||
首次运行会自动安装前后端依赖(约 1-2 分钟),之后直接启动:
|
||||
|
||||
@@ -220,6 +235,9 @@ pnpm dev # http://localhost:3011
|
||||
> **启用回测**:`cd backend && uv sync --extra backtest`
|
||||
> vectorbt → numba 体积较大,故作为可选 extras。macOS / Intel 无预构建 wheel 时需 `brew install cmake` 现场编译。
|
||||
|
||||
> **老 CPU 兼容**:`cd backend && uv sync --extra legacy-cpu`
|
||||
> 当机器缺少 `avx2/fma` 等指令集时,给 Polars 切到 `rtcompat` 运行时。
|
||||
|
||||
---
|
||||
|
||||
## 🧭 第一次使用
|
||||
|
||||
@@ -35,6 +35,13 @@ dependencies = [
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
# Legacy CPU runtime: install the Polars compatibility kernel on
|
||||
# machines without AVX2/FMA support.
|
||||
# Enable with: uv sync --extra legacy-cpu
|
||||
legacy-cpu = [
|
||||
"polars[rtcompat]>=1.0",
|
||||
]
|
||||
|
||||
# 回测依赖 vectorbt → numba → llvmlite,体积大且 macOS/Intel 上无预构建 wheel 时
|
||||
# 需要 brew install cmake 现场编译。挪到可选 extras,主依赖瘦身。
|
||||
# 启用:`uv sync --extra backtest`
|
||||
|
||||
Generated
+27
-2
@@ -1541,6 +1541,11 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ea/91/74fc60d94488685a92ac9d49d7ec55f3e91fe9b77942a6235a5fa7f249c3/polars-1.40.1-py3-none-any.whl", hash = "sha256:c0f861219d1319cdea45c4ce4d30355a47176b8f98dcedf95ea8269f131b8abd", size = 828723, upload-time = "2026-04-22T19:14:25.452Z" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
rtcompat = [
|
||||
{ name = "polars-runtime-compat" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polars-runtime-32"
|
||||
version = "1.40.1"
|
||||
@@ -1557,6 +1562,22 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/65/ad/b33c3022a394f3eb55c3310597cec615412a8a33880055eee191d154a628/polars_runtime_32-1.40.1-cp310-abi3-win_arm64.whl", hash = "sha256:b5cbfaf6b085b420b4bfcbe24e8f665076d1cccfdb80c0484c02a023ce205537", size = 45822104, upload-time = "2026-04-22T19:14:54.192Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polars-runtime-compat"
|
||||
version = "1.40.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4c/60/f8340030f94a45231ad02abff171c8c10f45df0984e5a4fd0f39a48500f4/polars_runtime_compat-1.40.1.tar.gz", hash = "sha256:6149aa764439cec26a5f883fb9921a50f61a0f6c4549df51c735626701a73a18", size = 2935443, upload-time = "2026-04-22T19:16:00.906Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/07/c7/978481a2a2f5b50636d485bc176e16084fa1bb3b1d7e7e34f580cef240dc/polars_runtime_compat-1.40.1-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:a683d287237f1dcc3dee95b5b2b6408cec318abbbb412ca49206492513be862f", size = 52016973, upload-time = "2026-04-22T19:15:25.228Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/c9/e308b0bbb331330a762f5f495597d34e9933c965ca6d4026a2eb481ef4ad/polars_runtime_compat-1.40.1-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:c83750f5593cec088134614fbf783fd10c5a92030d71b35f3dea0fff682d92c6", size = 46246682, upload-time = "2026-04-22T19:15:28.666Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/54/eaecb4747695e2e200ed6d13ce40dd7b0cdc7499d0b9af1e64e83af0e46d/polars_runtime_compat-1.40.1-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffa15c4a8b7f67911412c849dc3d3aac313f682d834eb3f374d0f6cb7e080efc", size = 50123217, upload-time = "2026-04-22T19:15:32.321Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/87/0a881905d94341111d38e6a7ae94674511e6797cf3be2500998f06963edf/polars_runtime_compat-1.40.1-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0373dabf942135d13b453d50be7a84b14420b495bd1242570545f58866396e7", size = 55869626, upload-time = "2026-04-22T19:15:37.15Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/6e/ac57e39bb94ebd63d6714895881ee0461e39039daa208916e5cad93174f9/polars_runtime_compat-1.40.1-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:bcdc488472d2c57dd3315a897456b47cdac222a1520fcf3d8d38410a5bf47ec1", size = 50287716, upload-time = "2026-04-22T19:15:40.829Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/f3/b75afc9f79cd4cadff52bdc4566119892b378f739a295573bf6bd0190a6c/polars_runtime_compat-1.40.1-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:34d03962169fc7c0ef6f6efd324d0a51350e7b5abf3b0cd118eb7a32e4d947ec", size = 53796312, upload-time = "2026-04-22T19:15:44.68Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/68/0df61011d894d1c94c915b39423c9aab79b3f7b18b836031ed32987227e0/polars_runtime_compat-1.40.1-cp310-abi3-win_amd64.whl", hash = "sha256:d9ccfe58eeb776567cf9556a83b980b9face9f0b1bb629bf2cd2334f4d9daf57", size = 51696665, upload-time = "2026-04-22T19:15:48.65Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/01/1bc7e868d3e4055b1ae756ad8ccc2a5d2bce57d7c88c3b4427babd43450b/polars_runtime_compat-1.40.1-cp310-abi3-win_arm64.whl", hash = "sha256:0c662e6acf5d4e3784eee8e8a1ec6eb185132ac90689cb84034132b5787903b1", size = 45701223, upload-time = "2026-04-22T19:15:52.189Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prompt-toolkit"
|
||||
version = "3.0.52"
|
||||
@@ -2470,7 +2491,7 @@ all = [
|
||||
|
||||
[[package]]
|
||||
name = "tickflow-stock-panel-backend"
|
||||
version = "0.1.44"
|
||||
version = "0.1.45"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "apscheduler" },
|
||||
@@ -2508,6 +2529,9 @@ dev = [
|
||||
{ name = "pytest-asyncio" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
legacy-cpu = [
|
||||
{ name = "polars", extra = ["rtcompat"] },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
@@ -2522,6 +2546,7 @@ requires-dist = [
|
||||
{ name = "platformdirs", specifier = ">=4.0" },
|
||||
{ name = "plyer", specifier = ">=2.1" },
|
||||
{ name = "polars", specifier = ">=1.0" },
|
||||
{ name = "polars", extras = ["rtcompat"], marker = "extra == 'legacy-cpu'", specifier = ">=1.0" },
|
||||
{ name = "pyarrow", specifier = ">=16.0" },
|
||||
{ name = "pydantic", specifier = ">=2.7" },
|
||||
{ name = "pydantic-settings", specifier = ">=2.4" },
|
||||
@@ -2538,7 +2563,7 @@ requires-dist = [
|
||||
{ name = "vectorbt", marker = "extra == 'backtest'", specifier = ">=0.26" },
|
||||
{ name = "winotify", marker = "sys_platform == 'win32'", specifier = ">=1.1" },
|
||||
]
|
||||
provides-extras = ["backtest", "desktop", "dev"]
|
||||
provides-extras = ["legacy-cpu", "backtest", "desktop", "dev"]
|
||||
|
||||
[[package]]
|
||||
name = "tqdm"
|
||||
|
||||
@@ -5,6 +5,8 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
BACKEND_EXTRAS: ${BACKEND_EXTRAS:-}
|
||||
container_name: TickFlow_Stock_Panel
|
||||
ports:
|
||||
- "${PORT:-3018}:3018"
|
||||
|
||||
Reference in New Issue
Block a user