一个简洁的本地视频管理后台。管理员可分片上传、断点续传和管理视频,访客通过公开地址直接播放。系统不转码;浏览器不支持源文件编码时,播放页会显示兼容性提示。
apps/
api/ NestJS API
prisma/ 数据模型、初始化与超级管理员种子
src/auth/ 登录与权限
src/users/ 管理员账号
src/uploads/ 分片和断点续传
src/videos/ 视频管理与 Range 播放
src/audit/ 审计记录
web/ Vue 3 管理端与公开播放页
src/components/ 通用组件
src/layouts/ 后台布局
src/stores/ 登录状态
src/views/ 页面
deploy/nginx.conf 反向代理配置
docker-compose.yml 从源码构建的容器部署
docker-compose.hub.yml 从 Docker Hub 拉取的生产部署
.github/workflows/ GitHub Actions 镜像构建发布
data/ 数据库、视频和临时分片(不会提交)
需要 Node.js 20+ 和 Yarn 1.22。项目默认使用 Yarn,国内镜像已在 .yarnrc 中配置。
corepack enable
yarn install
cp .env.example .env
yarn db:generate
yarn db:bootstrap
yarn db:seed
yarn devWindows PowerShell 使用:
corepack enable
yarn install
Copy-Item .env.example .env
yarn db:generate
yarn db:bootstrap
yarn db:seed
yarn dev打开 http://localhost:5173。开发环境初始账号来自 .env:
- 用户名:
admin - 密码:
ChangeMe123!
首次部署前必须修改 JWT_SECRET 和 SUPER_ADMIN_PASSWORD。超级管理员只会在数据库中不存在超级管理员时创建,之后修改环境变量不会覆盖现有账号。
先准备 .env,至少设置实际域名、随机 JWT 密钥和强管理员密码:
cp .env.example .env
mkdir -p data
docker compose -f docker-compose.hub.yml pull
docker compose -f docker-compose.hub.yml up -d默认拉取:
byterk/video-service-api:latestbyterk/video-service-web:latest
使用指定版本:
IMAGE_TAG=1.2.3 docker compose -f docker-compose.hub.yml up -dLinux 或装有 Docker Desktop 的 Windows 均可运行:
cp .env.example .env
# 修改 .env 中的密码、密钥、域名
docker compose up -d --build两种部署方式均将持久化内容保存在宿主机 ./data。API 容器启动时会幂等初始化数据库结构和超级管理员。
生产环境建议在 Nginx 或云负载均衡前配置 HTTPS,并将:
APP_ORIGIN、PUBLIC_BASE_URL设置为实际 HTTPS 域名。JWT_SECRET设置为至少 32 位随机字符串。SUPER_ADMIN_PASSWORD设置为强密码。HTTP_PORT设置为需要暴露的端口。
工作流文件为 .github/workflows/docker-publish.yml,分别构建 API 和 Web 的 linux/amd64、linux/arm64 镜像。
在 GitHub 仓库的 Settings → Secrets and variables → Actions 中创建 Repository secret:
- 名称:
DOCKERHUB_TOKEN - 内容:Docker Hub 为用户
byterk创建且具有 Read & Write 权限的 Access Token,不要使用账号密码。
首次运行工作流前,确认 Docker Hub 的 byterk 命名空间下已存在 video-service-api 和 video-service-web 两个仓库。
发布规则:
- Pull Request 到
main:只构建验证,不登录、不推送。 - 推送到
main:发布latest和sha-<commit>。 - 推送
v1.2.3标签:发布1.2.3、1.2、1和sha-<commit>。 - Actions 页面手动运行:发布当前提交的
sha-<commit>。
创建版本发布示例:
git tag v1.2.3
git push origin v1.2.3| 变量 | 默认值 | 用途 |
|---|---|---|
PORT |
3000 |
API 端口 |
HTTP_PORT |
80 |
Docker Web 服务映射到宿主机的端口 |
IMAGE_TAG |
latest |
docker-compose.hub.yml 使用的镜像标签 |
APP_ORIGIN |
http://localhost:5173 |
允许访问 API 的前端来源,多个值用逗号分隔 |
DATABASE_URL |
SQLite 本地文件 | 数据库地址 |
STORAGE_DIR |
data/videos |
视频存储目录 |
UPLOAD_TEMP_DIR |
data/tmp |
临时分片目录 |
UPLOAD_WARNING_BYTES |
20971520 |
上传提醒阈值(20 MB) |
UPLOAD_CHUNK_BYTES |
5242880 |
分片大小(5 MB) |
UPLOAD_SESSION_HOURS |
24 |
未完成分片保留时间 |
LOGIN_RATE_LIMIT |
10 |
15 分钟内单 IP 登录尝试次数 |
上传大小没有业务层上限。若调整分片超过 8 MB,需要同步增大 deploy/nginx.conf 中的 client_max_body_size。
非 Docker 开发环境修改根目录 .env 中的 PORT 后,NestJS 监听端口和 Vite /api 代理会同步变更,无需再修改前端配置。
服务端保留原文件且不转码。是否能播放取决于客户端对文件封装、视频编码和音频编码的支持。MP4(H.264 + AAC)兼容范围通常最好。公开视频接口支持 HTTP Range,可拖动进度并按需加载。
- 备份:停止写入后备份整个
data目录,包括 SQLite 数据库和videos文件夹。 - 恢复:将备份恢复到相同目录并重新启动服务。
- 停用视频只改变状态并保留文件;删除视频会永久删除数据库记录和本地文件。
- 视频列表分别显示播放页浏览量和实际播放量;同一次页面打开只在首次开始播放时累计一次播放量。
- 超过
UPLOAD_SESSION_HOURS的未完成分片会在 API 启动时清理。
yarn dev # 前后端开发服务
yarn build # 生产构建
yarn test # 后端测试
yarn db:generate # 生成 Prisma Client
yarn db:bootstrap # 幂等初始化 SQLite 表
yarn db:seed # 初始化超级管理员