商用虚拟机切片管理面板,包含用户中心、套餐与实例管理、工单系统、公告系统、管理员后台、宿主机 Agent 网关、同域 /api 接口与 Docker 一键构建部署能力。
最后更新:2026-06-26(按当前仓库代码同步)
- 项目截图
- 项目概览
- 技术栈与运行环境
- 项目结构
- 快速开始(本地开发)
- 环境变量
- 数据库与展示数据
- 后端 API 模块总览
- 前端页面与路由
- Agent 与宿主机对接说明
- Docker 构建与部署
- 常用开发/运维命令
- 常见问题
PizzaBox 面向“把一台宿主机切成多个可售卖实例”的业务场景,当前仓库已包含以下核心能力:
- 用户注册、登录、会话管理与个人设置
- 资源池分类、宿主机节点、套餐管理
- 套餐购买、实例创建、实例详情、续费与管理员操作
- 全局系统镜像目录管理,并与套餐可选系统联动
- 工单系统(用户提交/回复 + 管理员处理)
- 公告系统、通知系统、推广返利、优惠券与账单管理
- 宿主机 Agent WebSocket 网关与实例操作下发
- 同域
/api接口模式 - 单容器 Docker 构建与部署脚本
- Node.js + Express
- Prisma + SQLite
- JWT 鉴权
- Multer(图片上传)
- WebSocket(宿主机 Agent 通信)
- Morgan / CORS
- React 19
- Vite 8
- React Router 7
- Tailwind CSS 4
- Go
- 负责宿主机状态上报、实例创建/删除/重装等动作执行
- Node.js 20+
- npm 10+
- SQLite(通过 Prisma 使用)
- Docker / Docker Buildx(可选)
PizzaBox/
├── agent/ # 宿主机 Agent 与相关脚本
│ ├── main.go
│ ├── lxd/
│ ├── metrics/
│ └── build.sh
├── backend/ # 后端服务
│ ├── package.json
│ ├── prisma/
│ │ ├── schema.prisma # Prisma 数据模型
│ │ ├── seed.js # 展示数据种子脚本
│ │ ├── pizzabox.db # SQLite 数据库
│ │ └── backups/ # 数据库备份
│ ├── src/
│ │ ├── app.js # 后端入口,挂载 API、静态站点与 Agent 网关
│ │ ├── controllers/ # 业务控制器
│ │ ├── routes/ # API 路由
│ │ ├── middlewares/ # 鉴权中间件
│ │ ├── services/ # 业务服务层
│ │ ├── utils/ # 工具与网关
│ │ └── crons/ # 定时任务
├── frontend/ # 前端工程
│ ├── package.json
│ ├── vite.config.js
│ ├── index.html
│ └── src/
│ ├── App.jsx # 前端路由入口
│ ├── components/ # 通用组件
│ ├── pages/ # 用户页与管理页
│ ├── utils/ # API、站点配置、系统镜像等工具
│ └── assets/ # 图标与图片资源
├── secrets/ # 支付证书等敏感文件目录
│ └── alipay/
├── Dockerfile # 单容器镜像构建
├── .dockerignore
├── .env.example # 示例环境变量
├── build.sh # 构建 amd64 镜像 + 导出 tar/zip
├── deploy.sh # 本地镜像部署脚本
├── IMPORTANT.txt # Docker 发布包说明(构建时自动补)
└── README.md
cd backend && npm install
cd ../frontend && npm installcp .env.example .env本地开发至少建议填写:
JWT_SECRETPORTURL
如果不填:
PORT默认走5001URL代码里默认会回退到http://localhost:5173
cd backend
npx prisma db push
node prisma/seed.js建议两个终端分别启动:
# 终端 1:后端(默认 :5001)
cd backend
npm run dev
# 终端 2:前端(默认 :5173)
cd frontend
npm run dev当前前端通过 Vite 代理:
/api->http://localhost:5001/uploads->http://localhost:5001
以根目录 .env.example 为基础,当前代码实际会读到这些变量。
| 变量 | 用途 | 示例 |
|---|---|---|
PORT |
后端监听端口 | 5001 |
JWT_SECRET |
JWT 签名密钥 | change_me |
NODE_ENV |
运行环境 | development / production |
DATABASE_URL |
Prisma SQLite 数据库路径 | file:./pizzabox.db 或 file:/app/backend/prisma/pizzabox.db |
URL |
用于邀请链接等站点地址生成 | http://localhost:5173 |
VITE_API_URL |
前端 API 基址,默认可不填 | /api |
根目录 .env.example 当前内容:
PORT=5001
JWT_SECRET=change_me
NODE_ENV=production
DATABASE_URL="file:/app/backend/prisma/pizzabox.db"
URL=http://localhost:5001
VITE_API_URL=/api说明:
- 本地开发时,后端代码通过
dotenv从根目录.env读取变量 - 前端默认直接走同域
/api,通常不需要额外设置VITE_API_URL
- 当前项目使用 SQLite
- Prisma schema 位于 backend/prisma/schema.prisma
- 默认数据库文件位于 backend/prisma/pizzabox.db
cd backend
npx prisma db push
npx prisma generate
node prisma/seed.jsbackend/prisma/seed.js 目前会生成演示数据,包括:
- 管理员用户
- 普通用户
- 公告
- 工单与对话
- 节点
- 资源池分类
- 套餐
- 虚拟机实例
- 账单
- 通知
- 会话
- 优惠券与返利演示数据
- 管理员
- 邮箱:
admin@pizzabox.io - 用户名:
admin - 密码:
admin123
- 邮箱:
- 普通用户 1
- 邮箱:
alice@example.com - 用户名:
alice - 密码:
123456
- 邮箱:
- 普通用户 2
- 邮箱:
bob@example.com - 用户名:
bob - 密码:
123456
- 邮箱:
后端入口位于 backend/src/app.js。
当前主要 API 前缀如下:
| 前缀 | 说明 |
|---|---|
/api/auth |
注册、登录、验证码、重置密码、用户会话 |
/api/configs |
系统配置、公共站点配置、系统设置、后台控制台信息 |
/api/announcements |
公告查询与管理 |
/api/admin/tickets |
管理员工单处理 |
/api/tickets |
用户工单 |
/api/plans |
套餐查询与管理 |
/api/categories |
资源池分类 |
/api/admin/nodes |
宿主机节点管理 |
/api/admin/users |
用户管理 |
/api/admin/coupons |
优惠券管理 |
/api/referrals |
推广返利、提现 |
/api/instances |
实例购买、详情、动作、管理员实例管理 |
/api/invoices |
账单查询与管理 |
/api/payments |
支付订单、支付宝当面付链路 |
/api/notifications |
用户通知 |
/api/configs/upload |
图片上传接口 |
静态资源与站点入口:
/uploads/*:上传文件- 非
/api与/uploads路径:在生产模式下由后端直接返回前端dist
前端入口位于 frontend/src/App.jsx。
/login登录 / 注册 / 找回密码/dashboard仪表盘/purchase购买服务/management管理服务/management/details/:id服务器详情/tickets工单管理/billing个人账单/promotion推广返利
/admin/console控制台/admin/users用户管理/admin/user-servers用户服务器列表/admin/servers服务器管理/admin/plans套餐设置/admin/coupons优惠券设置/admin/billing全站账单/admin/tickets全站工单/admin/announcements公告管理/admin/system系统设置
- 管理端页面通过前端
AdminRoute做基础权限守卫 - 站点名称、Favicon 与副标题通过
/api/configs/public动态同步
agent/ 目录是 PizzaBox 的宿主机侧代理程序。
当前职责:
- 向主站回报宿主机状态
- 接收主站下发的实例动作指令
- 负责实例创建、删除、重装、启动、停止等宿主机操作
当前仓库中:
- 后端通过 WebSocket 初始化 Agent 网关
- Agent 相关管理逻辑位于 backend/src/utils/agentManager.js
- 宿主机侧实现位于 agent/
如果你要真正接生产宿主机,除了主站外,还需要单独部署并配置对应的 Agent。
chmod +x build.sh
./build.sh也可以直接指定版本:
./build.sh 1.0.0当前 build.sh 会:
- 使用
docker buildx构建linux/amd64镜像 - 默认镜像名:
pizzabox:<tag> - 自动导出 tar 到
release/ - 自动打包 zip 发布包到
release/
生成物示例:
release/pizzabox-1.0.0-amd64.tarrelease/Docker-pizzabox-1.0.0-amd64.zip
chmod +x deploy.sh
./deploy.sh 1.0.0当前 deploy.sh 会:
- 检查本地镜像是否存在
- 自动准备
./data/db与./data/uploads - 若根目录没有
.env,则从.env.example复制 - 自动修正
.env中的PORT / DATABASE_URL / NODE_ENV / VITE_API_URL - 删除旧容器
- 启动新容器
默认行为:
- 容器名:
pizzabox - 映射端口:
5001:5001 - 数据库存放:
./data/db/pizzabox.db - 上传文件存放:
./data/uploads
访问地址:
- 前台:
http://localhost:5001 - API:
http://localhost:5001/api
当前 Dockerfile 使用多阶段构建:
- 构建前端
dist - 安装后端依赖并生成 Prisma Client
- 将前端静态文件与后端一起打进最终镜像
因此生产环境下只需要一个容器即可同时提供:
- 前端页面
/api接口/uploads资源
cd backend && npm run dev
cd frontend && npm run devcd frontend
npm run buildnode --check backend/src/app.jscd backend
npx prisma db push
npx prisma generate
node prisma/seed.js./build.sh 1.0.0
./deploy.sh 1.0.0
docker logs -f pizzabox
docker ps- 检查后端是否已启动在
5001 - 本地开发确认
frontend/vite.config.js的/api代理是否生效 - 若是 Docker 部署,确认容器已成功启动且
.env中PORT=5001
- 检查浏览器本地
token与user是否被清空 - 检查
JWT_SECRET是否在服务重启前后发生变化 - 检查后端是否返回了 401 / 403
- 当前本地数据库默认在
backend/prisma/pizzabox.db - Docker 部署时数据库持久化在
./data/db/pizzabox.db - 若要保留旧数据,先手动备份数据库文件
- 检查
backend/uploads或 Docker 下的./data/uploads - 确认访问路径是否为
/uploads/... - 确认后端容器有对应目录挂载权限
deploy.sh当前默认从本地 Docker 镜像仓库读取镜像- 如果你是把 tar 发到另一台机器,需要先
docker load -i xxx.tar,或者后续把deploy.sh扩成支持直接从 tar 导入
- 这类情况主站页面仍可展示实例记录
- 但真正的开机、关机、删除、重装动作依赖宿主机 Agent 在线
请在商用、二次分发或对外部署前,自行确认依赖许可证、支付证书、Agent 侧脚本与宿主机控制链路的合规要求。