Skip to content

单机版部署(三容器) ​

一台 Linux 服务器,一份 .env,一条 sudo ./install.sh,跑起三个容器:YiYi-media-standalone + YiYi-media-standalone-postgres + YiYi-media-standalone-redis。Storage 与 Play Agent 已内置,无需安装任何节点。

这一页是**单机版部署(STANDALONE)**的安装流程,用的是部署仓库 YiYi-media-deploy:只从 ghcr.io 拉预构建镜像,不在服务器上构建任何东西,目标机不需要源码、Maven、Node 或 Go。

需要外部工作节点与横向扩容时,走分布式部署:控制面同机(一台服务器)或按角色多机(至少四台)。

前置条件 ​

项目要求
机器与权限一台 Linux 服务器,有公网 IP 或已解析的域名,能用 sudo 执行 install.sh
DockerDocker Engine + Compose v2,docker info 可用;openssl、curl、python3 脚本启动即检查,缺一个直接退出
地址服务器 IP 或域名,不带 http:// 前缀和路径
授权与出站网络一个 edition=STANDALONE 的一次性授权码;能访问 YIYI_LICENSE_SERVER_URL 指向的授权中心(HTTPS)。授权公钥由脚本自动下载,不需要手工放文件
端口18080 与 19090 都发布到宿主机;19090 是播放客户端直连端口,不用反代也能用
磁盘数据目录默认在 /opt/YiYi-media-deploy/data/,需容纳数据库、上传文件、Storage 数据与日志
bash
docker compose version
docker info >/dev/null && echo "daemon ok"
for tool in docker openssl curl python3; do command -v "$tool" >/dev/null || echo "缺 $tool"; done

不需要预装 PostgreSQL、Redis、Storage 或 Play Agent

单机版由部署包统一提供 postgres 与 redis 容器,Storage 与 Play Agent 则在应用容器内随主应用一起启动。 你不需要另外准备任何节点机器。

第 1 步:克隆仓库并准备 .env ​

部署仓库按部署形态分成三个 Git 分支,每个分支根目录都是一套完整的部署文件:

分支形态
main(本页)单机版,三容器
v2-all-in-one分布式,控制面全部在同一台机器
v3-multi-host分布式,控制面按角色分散到多台机器
bash
# main 即单机版
git clone https://github.com/YiYi-Product/YiYi-media-deploy.git /opt/YiYi-media-deploy
cd /opt/YiYi-media-deploy
cp .env.example .env
chmod 0600 .env

分支只决定部署形态,不决定产品能力

三种形态共用同一套产品镜像与同一套权限边界。切换形态不能靠换分支原地完成, 必须走授权的版本升级操作,见单机版迁移到分布式版。

单机版不生成 join.env

单机版是单机部署形态,不生成 join.env,也没有集群中继证书的概念。 join.env 只属于分布式部署(按角色多机)。

第 2 步:填写 .env ​

单机版你真正要填的只有服务器地址一项,其余保持模板默认即可:

dotenv
YIYI_SERVER_HOST=<你的服务器IP或域名>
# 例如:YIYI_SERVER_HOST=203.0.113.10
变量单机版怎么填说明
YIYI_SERVER_HOST必填服务器 IP 或域名,不带协议与路径
YIYI_LICENSE_SERVER_URL保持模板值<发布方提供的授权中心地址>,不带路径的 HTTPS 地址;脚本从这里下载授权公钥
YIYI_DATA_DIR留空留空 = 部署目录下的 data/。可填绝对或相对路径(相对以部署目录为基准)
YIYI_STORAGE_MOUNT_DIR可选挂载文件夹(Storage 挂载数据根)单独放到别的盘时填,如 /mnt/big/yiyi-mounts;留空 = <YIYI_DATA_DIR>/storage/mount-data
YIYI_PLAY_AGENT_VFS_CACHE_DIR可选VFS 内容缓存放到更快的盘(SSD)时填,如 /mnt/ssd/yiyi-vfs;留空 = <YIYI_DATA_DIR>/play-agent/vfs-cache
YIYI_DB_USER保持 yiyi数据库用户
YIYI_DB_PASSWORD、YIYI_SERVICE_TOKEN保持 GENERATE_ON_INSTALL数据库口令与服务间鉴权令牌,脚本用 openssl rand -hex 32 生成并回写
YIYI_REDIS_PASSWORD留空留空表示不启用 Redis 密码;填 GENERATE_ON_INSTALL 才自动生成
YIYI_TELEGRAM_*、YIYI_GOOGLE_CLIENT_ID留空第三方登录都可选,留空不影响启动
YIYI_IMAGE_TAG建议填聚合镜像标签,统一由它锁定。留空使用可变的 latest;生产建议锁定到不可变版本
YIYI_APP_PORT / YIYI_APP_BIND_HOST18080 / 0.0.0.0宿主机上的 Web 入口端口与绑定地址
YIYI_PLAY_AGENT_PORT / YIYI_PLAY_AGENT_BIND_HOST19090 / 0.0.0.0Play Agent 的宿主机端口与绑定地址。默认对 0.0.0.0 发布,播放客户端可直连;若前面有 Caddy / nginx 反代,可改成 127.0.0.1
YIYI_PUBLIC_HOST建议填对外域名或公网 IP。留空时回退为 YIYI_SERVER_HOST。它同时用作内置 Play Agent 首次创建时的默认「对外地址」,填对可让用户播放线路开箱可用;之后可在「节点管理」里改

单机版没有角色与节点安装变量

单机版不使用 YIYI_DEPLOY_ROLE=single,也没有 Control/User/Media/Edge 角色选择, .env 里没有节点安装变量,也没有 join.env。看到「用 YIYI_DEPLOY_ROLE 切角色」 的说法,那是分布式部署的口径,见部署模式与版本选择。

YIYI_DEPLOYMENT_MODE=STANDALONE 由 install.sh 固定写入,只用于收窄能力; 真正的授权边界始终以签名租约里的 edition 为准,改它不会扩大授权范围。

凭据一律不要写进文档、命令行或提交记录

GENERATE_ON_INSTALL 是占位标记,脚本会替换成随机值并回写 .env。.env 权限保持 0600, 不要提交到 Git(.gitignore 已忽略它)。

第 3 步:执行安装脚本 ​

bash
sudo ./install.sh

脚本不接受任何参数,传参直接打印用法并退出。它按顺序做这些事:

  1. 检查 .env、命令行工具、Compose v2 与 daemon
  2. 创建统一数据目录并设置最小必要权限
  3. 确认四个数据库存在(缺失的按需创建,不覆盖已有库)
  4. 从授权中心下载授权公钥,校验通过后写入部署目录
  5. 拉取镜像,再 docker compose up -d --remove-orphans --wait 起服务并等健康检查
  6. 检查所有内部服务、两个内置节点与许可证状态
  7. 写入安装标记,打印访问地址

单机版的三个容器

标准安装完成后 docker compose ps 只应有三行:

服务名(compose 命令用)容器名(docker 命令用)
yiyi-appYiYi-media-standalone
postgresYiYi-media-standalone-postgres
redisYiYi-media-standalone-redis

docker compose 的命令与日志过滤用服务名(如 docker compose logs yiyi-app), docker exec / docker inspect 等直接用 docker 的命令用容器名。 多出其它业务容器说明用错了部署文件。

第 4 步:访问网页并激活授权 ​

安装成功后脚本会打印访问地址。浏览器打开:

text
http://<你的服务器IP或域名>:18080

第一个页面是授权激活页。按提示输入发布方提供的一次性授权码,激活成功后自动跳到创建管理员向导。

顺序是先激活、再建管理员

前端只在授权状态为 ACTIVE 或 GRACE 时才渲染创建管理员向导。授权激活全部在网页完成, 不需要命令行激活。细节见授权与版本与初始化与授权激活。

授权 Edition 必须与部署形态匹配

单机版只接受 edition=STANDALONE 的许可证。拿分布式版的许可证激活单机版镜像会被拒绝, 此时系统保留激活、许可证状态、日志和备份能力,不开放业务功能,不会删除任何数据。

生产环境还要在 18080 前面挂一层 HTTPS,见反向代理与域名。

第 5 步:确认内置节点在线 ​

单机版固定内置一个 Storage 与一个 Play Agent,随主应用安装、启动、升级:

内置节点节点 ID说明
Storagenode-local-storage文件管理、挂载源、刮削入库;自动成为新浏览器会话的默认文件管理节点
Play Agentnode-local-play-agent播放出口、直链与分段传输

节点 ID 可以不是 node-local-*

从旧部署迁入单机版时,安装脚本会沿用原有的节点 ID,并写进 YIYI_EMBEDDED_STORAGE_NODE_ID / YIYI_EMBEDDED_PLAY_AGENT_NODE_ID。 这样媒体源引用、用户播放线路授权与历史任务关联都不会失联。 全新安装才使用上面的默认 ID。

到后台 节点管理 确认两者都是「在线」,并显示「随系统部署 / 随主版本升级」。

单机版不提供节点安装入口

单机版的「节点管理」只能新增手动反代地址,没有「新增节点」按钮,也没有服务类型选择框。 内置节点不显示节点令牌、安装命令、卸载与独立升级操作。 后台服务端同样会拒绝新增外部节点(403 NODE_CREATION_DISABLED)、拒绝删除、卸载与独立升级 (403 SYSTEM_NODE_IMMUTABLE),并关闭节点二进制分发与安装命令 (403 BINARY_DISTRIBUTION_DISABLED)。所以这不是靠隐藏按钮实现的限制。

内置节点的对外地址可以改

内置节点可以编辑:名称、对外 IP 或域名、协议、对外端口与备注。 用自己的 Caddy / nginx 反代时,把「对外地址」填成反代域名与端口(例如 https + 443),用户播放线路就会下发这个地址。

内置节点的监听端口由应用容器固定(Play Agent 为 19090), 页面上不提供该输入框——它随主应用启动,改了也不会生效。

手动反代地址的登记方式见反向代理与域名,两种模式都支持。

数据目录 ​

数据根目录默认是 /opt/YiYi-media-deploy/data/:

txt
data/
├── postgres/                       # PostgreSQL 16 数据目录(四个业务库)
├── redis/                          # Redis AOF
├── license/
│   ├── identity/                   # 部署身份
│   └── lease/                      # 当前授权租约
├── config/uploads/                 # 后台上传的文件(Logo 等)
├── storage/
│   ├── mount-data/                 # 挂载数据
│   ├── spool/                      # 持久暂存区
│   └── read-cache/                 # 读缓存
├── play-agent/
│   ├── vfs-cache/                  # 视频缓存
│   ├── image-cache/                # 图片缓存
│   └── spool/                      # 调度回调暂存
└── logs/{config,user,media,gateway,storage,play-agent,license}/

其中两个目录可以单独放到别的磁盘(留空则保持在数据根目录内,行为不变):

目录变量为什么单独放
storage/mount-data/YIYI_STORAGE_MOUNT_DIR挂载文件夹体量大,常放独立大盘或 NAS
play-agent/vfs-cache/YIYI_PLAY_AGENT_VFS_CACHE_DIR播放缓存读写频繁,常放 SSD

两者互相独立,只改一个不影响另一个。安装脚本会创建目录并把属主设为 10001:10001(已存在的目录只补权限、不动内容);指向 / 或数据根目录这类会 破坏布局的取值会被直接拒绝。

单机版同一个 PostgreSQL 实例承载四个数据库:yiyi_config、yiyi_user、yiyi_media、yiyi_storage。表结构由各服务启动时自动迁移,不需要手工执行 SQL。

data/postgres 里是四个业务库,备份用 pg_dump 而不是拷目录;data/license/identity 是部署身份与密钥,丢了要找发布方重新绑定。备份清单见升级、备份与回滚。

端口与网络 ​

单机版使用 Compose 私有网络:

  • PostgreSQL 在容器内用 postgres:5432,Redis 用 redis:6379。
  • 应用容器内部服务互调用 127.0.0.1:<端口>。
  • 默认把前端 18080 与 Play Agent 19090 发布到宿主机。
  • Play Agent 19090 是播放客户端直连端口,默认对 0.0.0.0 发布。 若前面有反代,可把 YIYI_PLAY_AGENT_BIND_HOST 改成 127.0.0.1 只让本机反代访问。
  • Config、User、Media、Gateway、Storage、License Agent 的端口不发布到宿主机。
端口用途单机版暴露方式
18080前端与用户入口发布到宿主机,对用户开放
19090Play Agent发布到宿主机,播放客户端直连(可收窄为回环配合反代)
18085config 注册中心仅容器内部
18086gateway仅容器内部
18082 / 18083user / media仅容器内部
18084storage仅容器内部
18088license-agent仅容器内部
5432 / 6379PostgreSQL / RedisCompose 私有网络,不发布

对外开放 19090 时请限制来源

19090 默认对 0.0.0.0 发布,是为了让播放客户端能直接连上。 如果部署在公网,请用防火墙或安全组限制来源,或把它改回 127.0.0.1 并配合反代。

18083(media)默认不对外

18083 是 media 服务端口,单机版不发布到宿主机:所有浏览器与客户端请求都走 18080 的 nginx 入口,再由容器内部转发。只有分布式版才需要在私网内放行它。

主机 FUSE 挂载默认关闭 ​

单机版默认关闭主机 FUSE 挂载:聚合容器不使用 privileged,也不授予 SYS_ADMIN。 把 Storage 与其它服务放进同一个容器后,为挂载功能提权会让同一容器内的全部服务共享更高权限, 因此本期不做默认开启。

关闭 FUSE 主机挂载不影响这些能力:云盘管理、文件浏览、上传下载、媒体同步与刮削照常可用。 前端的能力接口会明确显示 FUSE 不可用及原因。

本期不做的事情

单机版不提供 Kubernetes、裸机 systemd 等其它交付形态,也不会把多个 Spring Boot 模块重构成一个 JVM 应用。 聚合的是容器与交付单元,Config、User、Media、Gateway、Storage 仍是各自独立运行的服务进程。

验证清单 ​

bash
cd /opt/YiYi-media-deploy

# 1. 恰好三个容器,全部 Up,(healthy)
docker compose ps

# 2. 授权状态与部署能力
curl -fsS http://127.0.0.1:18085/api/license/status
curl -fsS http://127.0.0.1:18085/api/config/deployment/capabilities

# 3. 四个库都建好了
set -a; . ./.env; set +a
docker compose exec -T postgres psql -U "$YIYI_DB_USER" -d postgres -c '\l' | grep yiyi

# 4. Web 入口
curl -fsSI http://127.0.0.1:18080/ | head -1

# 5. 内置节点健康(用服务名 exec,用容器名直连 docker)
docker compose exec -T yiyi-app curl -fsS http://127.0.0.1:18084/api/storage/ping
curl -fsS http://127.0.0.1:19090/health          # 已发布到宿主机,可直接探测

GET /api/config/deployment/capabilities 是管理员可读的部署能力接口,返回 edition、 deploymentMode、editionMatchesDeployment、externalManagedNodesAllowed、 nodeBinaryDistributionAllowed 与两个内置节点 ID。单机版下 externalManagedNodesAllowed 与 nodeBinaryDistributionAllowed 都是 false。

常用管理命令 ​

bash
cd /opt/YiYi-media-deploy
docker compose ps
docker compose stop
docker compose start
docker compose restart
docker compose down
docker compose up -d
docker compose logs --tail=100 yiyi-app      # 参数是 compose 服务名
docker logs --tail=100 YiYi-media-standalone # 容器名,等价

升级是整镜像升级,一次替换应用容器内全部服务:

bash
cd /opt/YiYi-media-deploy
docker compose pull
docker compose up -d --remove-orphans --wait
docker compose ps

详见升级、备份与回滚。

清空数据目录不可逆

rm -rf data/postgres 会删掉四个业务库的全部数据。执行前先做一次 pg_dump。

常见问题 ​

现象原因处理
脚本立刻退出并生成了一份 .env部署目录里没有 .env填好 YIYI_SERVER_HOST 再跑一次
请在 .env 中填写不带协议和路径的 YIYI_SERVER_HOST值带了 http://、路径或非法字符只填 IP 或域名,如 203.0.113.10、yiyi.example.com
未安装 python3 / 需要 Docker Compose v2 / Docker daemon 不可用缺工具,或连不上 Docker装齐 docker、openssl、curl、python3 与 Compose v2 插件;用 sudo
配置仍包含占位值.env 里还留着 GENERATE_ON_INSTALL 或 example.invalid多为手工改坏了生成项
docker compose ps 多于三个服务用错了部署文件或混入了旧的分布式 Compose单机版只应运行 yiyi-app、postgres、redis 三个服务
找不到 YiYi-media-standalone 容器该名字是容器名,不是 compose 服务名docker compose 用 yiyi-app;直接用 docker 时用 YiYi-media-standalone
激活被拒绝 / 提示版本不匹配授权 Edition 与部署形态不一致单机版要 edition=STANDALONE,见授权与版本
节点管理里找不到「新增节点」按钮单机版设计如此,只允许新增手动反代地址需要外部节点请走单机版迁移到分布式版
内置节点显示离线应用容器内部子进程未就绪docker compose logs --tail=200 yiyi-app,再看 docker compose ps 的健康状态
上传大文件报 413经 Web 入口的请求体受 nginx client_max_body_size 20m 限制分片上传由前端自动处理;直连受反代配置影响
页面能打开但所有接口 403授权未激活或已进入受限模式看返回里的 state 与 code,见授权与版本
docker compose pull 返回 401 / denied镜像包对你的账号不可见联系发布方确认拉取权限

相关文档 ​

自托管媒体管理系统(单机版 / 分布式版) · 想先体验或有问题,加 Telegram 群:t.me/yiyi_media_group