Metrix
Metrix 是一个轻量后台 Web 框架,当前提供登录、注册、RBAC 权限、用户管理、公告、操作日志、系统设置、API Token、API 文档、FTP/SFTP 储存管理、数据库管理、容器管理、脚本管理和标准 CRUD 示例模块。项目默认面向内网部署,所有 UI、图标、API 文档资源和运行依赖都需要本地安装或随构建产物提供,不依赖运行时外网资源。
新增页面、业务模块、权限、API 或数据库变更时,先阅读 DEVELOPMENT_GUIDE.md。
技术栈
- 前端:Vue 3、TypeScript、Vite、Naive UI、vue-i18n、Monaco Editor
- 后端:Python、FastAPI、SQLAlchemy、Pydantic
- 数据库:SQLite 或 MySQL
- 权限:账号密码登录、RBAC 资源动作权限、页面访问权限、本人/他人数据范围权限
目录结构
web/ 前端应用
src/modules/ 前端业务模块自动发现入口
src/i18n/locales/ 公共语言包
server/ Python 后端
app/modules/ 后端业务模块自动发现入口
app/api/ 内置 Web/API 接口
app/db/ 数据库连接、建表和同步
DEVELOPMENT_GUIDE.md 开发指南
docs/project_context.md 项目上下文历史归档(已冻结,记忆现由 MemRelay 维护)
runtime/ 本地运行时目录,默认不提交
标准示例模块:
- 前端:
web/src/modules/demo-crud - 后端:
server/app/modules/demo_crud - 测试:
server/tests/test_auth_rbac.py中的 demo CRUD 用例
文档入口:
DEVELOPMENT_GUIDE.md:新增模块、页面、权限、迁移和交互规范。docs/project_context.md:项目上下文历史归档(截止 2026-08-13,已冻结);此后项目记忆、决策与进度由 MemRelay 记录。
环境要求
- Python 3.11 或兼容版本
- Node.js 20.19+ 或 22.12+
- 可选:MySQL 8.x
快速启动
首次准备依赖:
python -m venv .venv
python -m pip install -r server/requirements.txt
cd web
npm install
开发模式(推荐,单窗口同时启动前后端,Ctrl+C 一次性停止):
python dev.py
dev.py 会在同一个终端窗口启动后端(uvicorn 自动重载,http://127.0.0.1:8000)和前端(Vite HMR,http://127.0.0.1:5173),并把两边日志以 [backend] / [web] 前缀合并输出;按一次 Ctrl+C 即可关闭两个服务及其子进程。
如需分开手动启动,后端 cd server && python main.py,前端 cd web && npm run dev。开发时访问 http://127.0.0.1:5173/install 初始化系统。
单端口部署(前后端同一端口):
cd web
npm install
npm run build
cd ../server
python main.py
构建完成后 python main.py 会自动检测 web/dist/,如果存在就在同一端口(默认 8000)同时提供 API 和前端页面,无需 Nginx。访问 http://127.0.0.1:8000/install 初始化系统。如果 web/dist/ 不存在则只启动 API 后端。
安装页会选择 SQLite 或 MySQL,并创建第一个管理员账号;项目没有硬编码默认管理员账号。
SQLite 路径留空时使用 runtime/metrix.db。如果从 server/ 执行 python main.py,启动入口会默认把 METRIX_RUNTIME_DIR 指向项目根目录下的 runtime/,避免写入 server/runtime/。如果使用虚拟环境,请先按当前系统和 shell 的标准方式激活,或直接使用对应环境中的 python。
常用配置
| 配置 | 说明 | 默认值 |
|---|---|---|
APP_NAME / METRIX_APP_NAME |
应用显示名称 | app.config.json 中的 appName |
APP_SLUG / METRIX_APP_SLUG |
本地存储 key 前缀 | 由应用名称生成 |
METRIX_RUNTIME_DIR |
运行时目录 | runtime |
METRIX_HOST |
后端监听地址 | 127.0.0.1 |
METRIX_PORT |
后端监听端口 | 8000 |
METRIX_RELOAD |
是否启用后端热重载 | 0 |
METRIX_ENABLED_MODULES |
后端只启用指定模块,逗号分隔,core 自动保留 |
空 |
METRIX_DISABLED_MODULES |
后端禁用指定模块,逗号分隔,不能禁用 core |
空 |
DOCKER_HOST |
容器管理模块自动检测 Docker daemon 时的优先候选地址,也可在系统设置中手动覆盖 | 自动检测 |
前端开发代理只代理 /api/ 和 /openapi.json 到 http://127.0.0.1:8000。不要把代理前缀改成宽泛的 /api,否则 /api-docs 页面刷新会被误转发到后端。
数据库管理模块支持 MySQL/MariaDB 连接、库表浏览、SQL 工作台、行级图形化增删改、SQL 脚本管理和 CSV/XLSX/SQLite/SQL 异步导入导出。导入/导出使用后台数据任务,系统设置页可调整“数据任务并发数”(默认 2,范围 1-16),任务完成后导出文件保留 24 小时或下载后清理。
容器管理模块通过 Docker SDK 连接当前部署宿主机的 Docker Engine,支持容器列表、创建、启动、停止、重启、日志、删除,以及镜像列表、导入、导出、删除和公共/私有可见性。Docker 连接可在系统设置中配置,默认自动检测 DOCKER_HOST、Linux/macOS socket、Windows named pipe 和本地 TCP,并使用第一个可连接地址。容器部署时通常需要挂载宿主机 socket:
-v /var/run/docker.sock:/var/run/docker.sock
-e DOCKER_HOST=unix:///var/run/docker.sock
Windows/macOS Docker Desktop 部署建议使用 Linux containers 模式;Windows 原生后端开发可在系统设置中手动填写 npipe:////./pipe/docker_engine。挂载 Docker socket 等同授予应用宿主机 Docker 高权限能力,只适合可信内网部署,不要把 Docker API 或容器管理接口暴露给不可信网络。
脚本管理模块以 Docker 容器隔离执行用户脚本:每个项目一个工作区目录 runtime/script_workspaces/u<owner>/p<id>/ bind-mount 到容器 /workspace,提供 Monaco 在线编辑、xterm 交互终端、手动运行与 APScheduler 定时调度(interval/cron)。复用容器模块解析的 Docker Host,绝不 pull 镜像(缺失提示去容器管理导入 tar);网络仅 none(断网)/bridge(接入网络)。包管理同时兼容内网离线与迁移联网:系统设置 script_pip_index_url/script_pip_trusted_host/script_npm_registry/script_go_proxy 默认空(留空联网走公共源、离线用 wheel/预装镜像,配置后走内网源),并可调整脚本运行并发数、运行记录保留时长和工作区配额。bind-mount 的是 Docker daemon 宿主机路径,后端需与 daemon 同主机且该盘对 daemon 可见;新增后端依赖 apscheduler。
初始化与数据库
- 开发期允许后端启动时自动建表、同步字段和同步权限种子。
- 后端模块可在
APP_MODULE中声明model_paths,框架建表前会自动导入模块模型。 - 后端模块可在
APP_MODULE中声明table_syncs,用于开发期轻量字段同步。 - 后端模块可声明
migrations,用于执行稳定、一次性的 SQL 迁移步骤;执行记录写入migration_records。 - 生产结构变更可使用显式 schema migration,修订文件位于
server/app/migrations/versions/,执行历史同样写入migration_records。 - 后端模块可声明轻量生命周期钩子
lifecycle_hooks,用于安装、升级、禁用和卸载时执行小型 SQL 步骤;模块状态记录写入module_states。 - 开发期字段同步也会写入
migration_records,用于追踪框架自动补齐过哪些字段。 - 生产部署前必须先备份数据库;结构变更应形成可追踪升级记录,不要直接在生产库手工改表。
- SQLite 与 MySQL 切换使用便携数据包迁移;迁移前先备份,迁移失败时使用保留的 zip 包重新导入回滚。
数据迁移辅助脚本:
cd server
python tools/migrate_database.py export --url "sqlite:///../runtime/metrix.db" --out "../runtime/backup.zip"
python tools/migrate_database.py import --url "sqlite:///../runtime/metrix-new.db" --in "../runtime/backup.zip"
python tools/migrate_database.py copy --from-url "sqlite:///../runtime/metrix.db" --to-url "sqlite:///../runtime/metrix-new.db" --backup "../runtime/rollback.zip"
python tools/migrate_database.py schema-status --url "sqlite:///../runtime/metrix.db"
python tools/migrate_database.py schema-new "add task indexes"
python tools/migrate_database.py schema-apply --url "sqlite:///../runtime/metrix.db"
python tools/migrate_database.py schema-rollback --url "sqlite:///../runtime/metrix.db"
python tools/migrate_database.py module-uninstall --url "sqlite:///../runtime/metrix.db" --module demo_crud --backup "../runtime/before-demo-uninstall.zip"
copy 会先导出源库并保留 --backup 指定的便携包,再导入目标库;如果目标库迁移失败,保留的 zip 就是回滚依据。MySQL URL 使用 SQLAlchemy 格式,例如 mysql+pymysql://user:pass@127.0.0.1:3306/metrix?charset=utf8mb4。
部署建议
- 后端安装 Python 依赖并设置运行时目录。
- 前端执行
npm run build生成web/dist。 - 内网 Web 服务器部署
web/dist静态文件。 - 反向代理
/api/、/openapi.json和/docs到后端服务。 - 备份
runtime/中的安装配置、SQLite 数据库和日志;MySQL 部署则按数据库规范备份。 - 确认服务器运行时不需要访问外网资源。
- 如果启用容器管理,确认 Docker daemon 只对可信环境开放,并在系统设置中使用自动检测或手动 Docker Host,同时按目标平台配置 TLS 或 socket 挂载。
后端可以继续用 python main.py 启动,也可以用进程管理器托管 uvicorn app.main:app。生产环境不要开启热重载。
Docker 离线部署
面向内网 Linux Docker 服务器,可先在有网构建机生成离线包:
python scripts/build_docker.py
产物位于 dist/docker/,包含 metrix-app-latest.tar、docker-compose.yml 和部署说明。目标服务器导入镜像后执行:
docker load -i metrix-app-latest.tar
docker compose up -d
如果需要随包带 MySQL 镜像:
python scripts/build_docker.py --include-mysql
详细说明见 packaging/README.md。
模块开发
新增业务优先按模块目录开发,不要分散修改框架核心文件。
生成完整 CRUD 模块骨架:
node scripts/create-module.mjs task "任务管理" "Tasks"
前端模块:
web/src/modules/<module>/
index.ts
api.ts
permissions.ts
views/
i18n/zh-CN.json
i18n/en-US.json
后端模块:
server/app/modules/<module>/
__init__.py
api.py
models.py
schemas.py
repositories.py
services.py
模块入口负责声明版本、依赖、页面、菜单、权限、API router、模型、迁移脚本、生命周期钩子和开发期字段同步。后端模块依赖可以写 core,也可以写 core>=0.1.0 这类版本约束;前端模块依赖使用精确模块 key。权限 code 统一使用 action:<resource>:<action>,页面和导航访问由对应资源的 action:<resource>:read 充当;如果涉及本人/他人数据边界,默认只能操作本人数据,需要额外声明 action:<resource>:manage_others。侧边栏默认把 系统管理 分组放在底部,新增业务模块和脚手架生成的导航菜单默认放在 系统管理 上方。
脚手架会生成前端 API/权限/CRUD 页面/i18n、后端 API/model/schema/repository/service/权限/审计和 pytest 模板;复杂业务字段继续在生成骨架上扩展。标准实现参考 demo-crud,开发规范见 DEVELOPMENT_GUIDE.md。
模块启停保持轻量:后端通过 METRIX_ENABLED_MODULES / METRIX_DISABLED_MODULES 控制,前端通过 app.config.json 的 enabledModules / disabledModules 或 VITE_ENABLED_MODULES / VITE_DISABLED_MODULES 控制。前端模块 key 使用短横线,后端模块 key 使用下划线。
后端会把已发现模块的版本、依赖和启用状态写入 module_states。禁用模块不会删除历史数据或权限;如果模块需要在禁用或卸载时执行归档/清理动作,应通过 lifecycle_hooks 显式声明,并通过 module-uninstall 命令执行卸载钩子。
测试与构建
后端:
python -m compileall -q server/app server/tests
python -m pytest
前端:
cd web
npm run test:regression:install
npm run test:smoke
npm run test:regression
npx vue-tsc --noEmit --noUnusedLocals --noUnusedParameters
npm run build
pytest 已在 pytest.ini 中配置临时目录;通常直接运行 python -m pytest 即可。
前端 smoke 会校验模块入口、模块 key、版本格式、依赖、菜单分组引用、页面路径、页面访问权限和模块语言包 key。首次运行 Playwright 回归前执行 npm run test:regression:install 下载 Chromium;当前回归覆盖安装守卫、匿名登录页、登录态恢复、模块页面和 404。新增模块后先跑 smoke 和回归测试,再做类型检查和构建。
License
PolyForm Noncommercial License 1.0.0
SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0