环境变量参考
YiYi Media 客户部署只有一份
.env,那是你唯一需要编辑的文件。安装脚本会往同一个.env里回写它自动生成与派生的变量(不要手改,下次安装会被覆盖),Compose 再把这些值拼成容器内服务真正读取的变量名。
怎么读这一页
事实来源是客户部署仓库 YiYi-media-deploy 的 .env.example、install.sh 与 部署仓库按部署模式分成三个 Git 分支,每个分支根目录都只有一份 compose.yaml: main(单机版)/v2-all-in-one(分布式·控制面同机)/v3-multi-host(分布式·多机)。本页按部署模式拆分:
- 第一节:单机版部署(三容器)—— 默认入门路径
- 第二节:分布式部署 —— Control/User/Media/Edge 与外部工作节点
- 第三节:两种模式共有的变量与机制
容器里的变量名大多不带 YIYI_ 前缀
服务进程读的是它自己的变量名,例如 SPRING_DATASOURCE_URL、REDIS_HOST,由部署配置用 .env 里的值拼出来。所以「改了 .env 没生效」通常不是变量名写错,而是中间变量被安装脚本按模式重写了。
一、单机版部署(三容器)
单机版把全部服务进程放进一个 yiyi-app 容器,因此 .env 里没有角色选择项, 也没有任何节点安装变量。你真正要填的只有 YIYI_SERVER_HOST(公网访问地址不同时 再加 YIYI_PUBLIC_HOST),以及发布方提供的 YIYI_LICENSE_SERVER_URL。
变量清单
| 变量 | 模板默认值 | 必填 | 作用 |
|---|---|---|---|
YIYI_SERVER_HOST | 空 | 是 | 本机地址或域名,不带协议和路径,只允许 0-9 A-Z a-z . _ - |
YIYI_PUBLIC_HOST | 空 | 否 | 公网访问地址;留空回退为 YIYI_SERVER_HOST。仅网页入口与服务器地址不同时才填 |
YIYI_LICENSE_SERVER_URL | 发布方提供的地址 | 是 | 授权中心 HTTPS 地址,必须是不带路径的 https://<host>[:<port>] |
YIYI_DATA_DIR | 空 | 否 | 持久化数据根目录。留空 = 部署目录下的 data;相对路径以部署目录为基准,脚本会规范化成绝对路径回写 |
YIYI_STORAGE_MOUNT_DIR | 空 | 否 | 可选:挂载文件夹(Storage 挂载数据根)的宿主目录。留空 = <YIYI_DATA_DIR>/storage/mount-data |
YIYI_PLAY_AGENT_VFS_CACHE_DIR | 空 | 否 | 可选:Play Agent VFS 内容缓存的宿主目录。留空 = <YIYI_DATA_DIR>/play-agent/vfs-cache |
YIYI_IMAGE_TAG | 空 | 建议填 | 聚合镜像标签,统一由它锁定。留空使用可变的 latest;生产应锁定到不可变的时间标签 |
YIYI_APP_PORT | 18080 | 否 | 宿主机上的 Web 入口端口,映射到应用容器内 18080 |
YIYI_APP_BIND_HOST | 0.0.0.0 | 否 | Web 入口绑定地址。前面另套 HTTPS 反代时可改为 127.0.0.1 |
YIYI_PLAY_AGENT_PORT | 19090 | 否 | 宿主机上的 Play Agent 端口 |
YIYI_PLAY_AGENT_BIND_HOST | 0.0.0.0 | 否 | Play Agent 的宿主机绑定地址。默认对 0.0.0.0 发布,播放客户端可直连;要只让本机反代访问就改成 127.0.0.1。对外开放时请用防火墙限制来源 |
YIYI_DB_USER | yiyi | 否 | 内置 PostgreSQL 用户 |
YIYI_DB_PASSWORD | GENERATE_ON_INSTALL | 是 | 数据库口令,见下文 GENERATE_ON_INSTALL 机制 |
YIYI_REDIS_PASSWORD | 空 | 否 | 留空 = 不启用 Redis 密码;填 GENERATE_ON_INSTALL 让脚本生成 |
YIYI_SERVICE_TOKEN | GENERATE_ON_INSTALL | 是 | 服务间鉴权令牌,见安全提示 |
YIYI_DEPLOYMENT_MODE | STANDALONE | 否,脚本维护 | 部署形态,安装脚本固定写成 STANDALONE。它只用于收窄能力:版本边界始终以签名租约里的 edition 为准,改它不会扩大授权范围 |
LOG_DIR | /data/logs | 否,Compose 固定 | 应用容器内各服务的日志根目录,落到 <data>/logs/ 下。不要手工改 |
单机版固定使用内置 PostgreSQL 与内置 Redis,四个业务库 (yiyi_config、yiyi_user、yiyi_media、yiyi_storage)由同一个实例承载, 数据库与缓存都不发布到宿主机。
其余 YIYI_LICENSE_* 由部署文件写死,不在 .env 里
应用容器内的授权文件路径(租约文件、授权公钥、原生验签库、部署身份目录)由部署文件 统一注入,聚合镜像内的授权代理与四个 Java 服务读的是同一组路径。你唯一需要填的授权相关 变量就是 YIYI_LICENSE_SERVER_URL;不要手工改动这些路径。
.env 示例(占位符,不要照抄真实值)
# 访问地址与授权中心
YIYI_SERVER_HOST=203.0.113.10
YIYI_PUBLIC_HOST=
YIYI_LICENSE_SERVER_URL=https://<发布方提供的授权中心地址>
# 持久化数据根目录(留空 = ./data)
YIYI_DATA_DIR=
# 镜像标签(建议锁定到不可变版本)
YIYI_IMAGE_TAG=
# 端口发布
YIYI_APP_PORT=18080
YIYI_APP_BIND_HOST=0.0.0.0
YIYI_PLAY_AGENT_PORT=19090
YIYI_PLAY_AGENT_BIND_HOST=127.0.0.1
# 内置 PostgreSQL 与 Redis
YIYI_DB_USER=yiyi
YIYI_DB_PASSWORD=GENERATE_ON_INSTALL
YIYI_REDIS_PASSWORD=
# 服务间鉴权令牌
YIYI_SERVICE_TOKEN=GENERATE_ON_INSTALL
# 第三方登录(可选,留空即不启用)
YIYI_TELEGRAM_BOT_TOKEN=
YIYI_TELEGRAM_BOT_USERNAME=
YIYI_TELEGRAM_MINIAPP_URL=
YIYI_TELEGRAM_WEBHOOK_SECRET=
YIYI_GOOGLE_CLIENT_ID=
# 以下由 install.sh 自动维护,不要手工修改
YIYI_DEPLOYMENT_MODE=STANDALONE
COMPOSE_PROFILES=Telegram 四项与 YIYI_GOOGLE_CLIENT_ID 留空即不启用对应登录方式。
单机版没有 join.env,也没有节点安装变量
单机版固定内置一个 Storage 与一个 Play Agent,它们随主应用安装、启动和升级。 因此 .env 里不会出现集群中继证书、许可证同步令牌,也没有角色选择 (YIYI_DEPLOY_ROLE、COMPOSE_PROFILES)或节点二进制安装相关配置。
数据目录结构
安装脚本会创建统一数据根下的子目录并设置最小必要权限:
<data>/
├── postgres/ # 内置 PostgreSQL 数据目录
├── 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}/- 首次安装用
chown -R递归改属主,之后的升级只改顶层目录,避免动到你的文件。 - 备份必须覆盖四个数据库、
data/license/、config/uploads/与 Storage 持久化目录, 详见升级、备份与回滚。 spool/属于必须保留的数据;read-cache/、vfs-cache/、image-cache/属于缓存, 可按恢复策略选择是否备份,但不能与 spool 混为一类。
二、分布式部署
分布式部署把控制面拆成 control、user、media、edge 四个内部角色, 并按许可证配额部署外部 Storage / Play Agent 工作节点。它由分布式分支(v2-all-in-one / v3-multi-host)的 compose.yaml 维护,不是单机版的另一种启动方式。
角色与需要填的变量
| 角色 | 你必须填 | 需要从 Control 拿 |
|---|---|---|
control | YIYI_SERVER_HOST(内网地址)、YIYI_USER_HOST;用外部数据库时再加 YIYI_DB_MODE=external 与 YIYI_DB_HOST / _PORT / _USER / _PASSWORD | — |
user | YIYI_SERVER_HOST(本机内网地址) | join.env + 集群中继证书 |
media | YIYI_SERVER_HOST(本机内网地址) | join.env + 集群中继证书 |
edge | YIYI_SERVER_HOST(本机内网地址)、YIYI_PUBLIC_HOST(公网地址) | join.env + 集群中继证书 |
安装顺序固定为 control → user → media → edge,且多台服务器必须位于同一私有网络。
分布式专属变量
| 变量 | 谁来填 | 说明 |
|---|---|---|
YIYI_DEPLOY_ROLE | 你填 | 分布式内部角色:control / user / media / edge。它不是独立部署模式 |
YIYI_DB_MODE | 你填 | bundled(默认,用内置 PostgreSQL)或 external(用你自备的实例) |
YIYI_DB_HOST / _PORT | external 时必填 | 不带协议和端口的主机名;端口校验为 1–65535 |
YIYI_DB_USER / _PASSWORD | external 时必填 | 外部实例的真实凭据 |
YIYI_USER_HOST | control 必填 | user 服务所在主机 |
YIYI_LICENSE_CLUSTER_TOKEN | 脚本生成,join.env 分发 | 集群许可证同步令牌,至少 32 字符,Control 与各节点必须一致 |
YIYI_LICENSE_SYNC_URL | 脚本写入 | 各节点拉取租约的地址,形如 https://<Control 主机>:18089/v1/lease |
许可证版本必须匹配部署形态
分布式部署只接受 edition=DISTRIBUTED 的许可证。如果拿到的是单机版许可证, 系统会保留激活、许可证状态、日志和备份能力,但不开放业务功能,也不会删除数据; 请向发布方签发分布式版许可证,或改用单机版三容器部署包。
反过来,单机聚合镜像只接受 edition=STANDALONE 的许可证。
集群加入文件
control 安装成功后会生成 join.env(chmod 0600)与集群中继证书。 把它们安全复制到 user / media / edge 服务器的同一目录,各节点的安装脚本会自动导入。
安装完成后删除其他节点上的 join.env
join.env 含数据库口令、服务令牌与集群令牌。它只用于其他服务器加入集群, 安装完成后应从其他服务器删除。
不要试图靠改 .env 从单机版升级到分布式版
单机版与分布式版互转必须同时完成许可证 Edition 变更、部署拓扑迁移和数据校验。 只改部署模式、Compose profile 或角色变量不会生效,也不是受支持的迁移路径。 见升级、备份与回滚。
三、两种模式共有的变量与机制
共有变量
| 变量 | 说明 |
|---|---|
YIYI_SERVICE_TOKEN | 服务间鉴权令牌。两种模式都必须设置,且已有部署不可重新生成,否则现有外部节点会鉴权失败 |
YIYI_LICENSE_SERVER_URL | 授权中心 HTTPS 地址,客户侧只需要能出网访问它 |
YIYI_DB_USER / YIYI_DB_PASSWORD | 数据库凭据;单机版用于内置 PostgreSQL,分布式版在 external 模式下用于外部实例 |
YIYI_REDIS_PASSWORD | Redis 口令;留空表示不启用 |
YIYI_DATA_DIR | 持久化数据根目录 |
YIYI_IMAGE_TAG | 镜像标签,建议锁定到不可变版本 |
YIYI_TELEGRAM_*、YIYI_GOOGLE_CLIENT_ID | 可选的第三方登录配置,只在 user 服务上生效 |
SMTP 不在环境变量里
注册验证码、账号找回、绑定验证码、密码重置与到期提醒用的 SMTP 参数在后台的注册设置里配置。
GENERATE_ON_INSTALL 机制
模板里的口令类变量填的是字面量 GENERATE_ON_INSTALL,安装脚本会把它换成 openssl rand -hex 32 生成的随机值并回写 .env(保持 chmod 0600):
- 值为空或等于
GENERATE_ON_INSTALL就生成:YIYI_DB_PASSWORD、YIYI_SERVICE_TOKEN - 值恰好等于
GENERATE_ON_INSTALL才生成:YIYI_REDIS_PASSWORD(留空是合法的「不启用密码」,所以走这条可选分支) - 生成后回写并保持
chmod 0600,第二次运行不会重复生成 - preflight 会拒绝任何残留占位值:
.env里只要有一行匹配GENERATE_ON_INSTALL或example.invalid,安装直接失败并报「配置仍包含占位值」
已有部署不能重新生成 YIYI_SERVICE_TOKEN
全局服务令牌不保存在 data 目录里。恢复旧数据库或迁移部署时如果让它静默生成新值, 现有外部节点会全部鉴权失败。安装脚本对此有硬保护:检测到 <data>/postgres 里已有 PostgreSQL 16 数据时,若 YIYI_DB_PASSWORD 或 YIYI_SERVICE_TOKEN 仍为空或 GENERATE_ON_INSTALL,脚本直接退出并要求你填写原值。
安装脚本做的一致性校验
安装脚本会在启动前校验并幂等补齐以下内容:
| 检查项 | 失败提示 |
|---|---|
.env 无占位值残留 | 配置仍包含占位值 |
关键变量非空且不以 REPLACE_ 开头 | 缺少 YIYI_xxx |
| 授权公钥与镜像内置的信任根一致 | 授权公钥缺失 / 授权服务器返回的公钥不受当前版本信任 |
部署配置可解析(docker compose config -q) | Compose 插值或语法错误 |
| 四个数据库存在(幂等,只创建缺失的) | 数据库准备失败 |
| 启动后内部服务、两个内置节点与许可证状态 | 健康检查失败 |
许可证状态接口在不可用时也返回 HTTP 200
/api/license/status 在许可证无效时仍返回 HTTP 200,状态在响应体的 state 字段里。 只判断 HTTP 码会把「许可证不可用」误报为安装成功。安装脚本解析 state, ACTIVE 与 GRACE 视为可用。如果你在自定义健康检查,请同样解析。
四、节点侧变量(仅分布式版)
外部 Storage 与 Play Agent 节点不由部署包安装:它们在分布式部署的「节点管理」里 创建后自助部署。单机版没有这一节对应的能力——单机版的两个节点是内置的, 随主应用安装、启动和升级,用户在「节点管理」中只能新增手动反代地址。
节点变量由一键安装脚本注入 systemd 的 EnvironmentFile(chmod 600), 不经过 .env。下面只列你真会调整的项。
play-agent
优先级:环境变量 > config.json > 内置默认值。config.json 默认从可执行文件同目录 或当前目录查找,路径可用 PLAY_AGENT_CONFIG 指定。
| 变量 | 内置默认 | 说明 |
|---|---|---|
PLAY_AGENT_LISTEN、PLAY_AGENT_PUBLIC_BASE_URL | :19090、空 → 自动拼 | 前者是进程实际监听地址,同机多实例必须各不相同;后者是客户端访问用的对外地址 |
PLAY_AGENT_CONFIG_BASE_URL | http://127.0.0.1:18085 | 注册中心地址。异机部署必须显式设置 |
YIYI_NODE_ID | 空 | 节点 ID。填了才会向 Config 查询对外地址并自动登记 |
PLAY_AGENT_SUPPORTED_PROTOCOLS | emby | 逗号分隔。当前只有 emby 有实现 |
PLAY_AGENT_VFS_CACHE_*、PLAY_AGENT_IMAGE_CACHE_*、PLAY_AGENT_RATE_LIMIT_ENABLED、PLAY_AGENT_METADATA_PROBE_ENABLED | 视频缓存 false;图片缓存 false;限速 true;探测 false | 建议在后台播放设置与缓存里按节点可视化配置。自带 ffprobe 仅用于元数据探测,不做转码 |
PLAY_AGENT_CDN_STATE_FILE | 二进制同目录的 cdnopt_state.json | CDN 优选 IP 池的持久化文件。官方 Docker 镜像已指到 /data/play-agent/cdnopt_state.json——二进制所在目录 /usr/local/bin 归 root,非 root 运行写不进去,优选结果就无法跨重启保留 |
PLAY_AGENT_SCHEDULER_CALLBACK_SPOOL_DIR | data/scheduler-callbacks/play-agent | 调度回调失败时的本地暂存目录(相对工作目录)。官方镜像已指到 /data/play-agent/spool |
两个令牌不通用:YIYI_SERVICE_TOKEN 是集群服务令牌,调用业务 API 用它; PLAY_AGENT_REGISTRY_TOKEN 是节点注册令牌,向注册中心发请求时只在它非空才带 X-Registry-Token 头。
storage(外部工作节点)
真实变量名带 STORAGE_MOUNT_ / STORAGE_TRANSFER_ 等前缀。
| 变量 | 默认 | 说明 |
|---|---|---|
STORAGE_MOUNT_DATA_DIR、STORAGE_MOUNT_SPOOL_DIR | /opt/yiyi、空 | 挂载数据根目录;持久暂存区,写入先落这里再由任务链路上传 |
STORAGE_MOUNT_DISK_CACHE_ENABLED / _DIR / _MAX_SIZE | false / <数据目录>/read-cache / 50GB | 远端文件分块落盘的读缓存 |
STORAGE_REGISTRY_CONFIG_SERVER、STORAGE_REGISTRY_HOST / _IP / _PORT | http://127.0.0.1:18085、127.0.0.1 / 空 / 18084 | 注册中心地址;登记的地址与端口 |
YIYI_NODE_ID | 见下方警告 | 节点 ID,每个节点必须各不相同 |
YIYI_SERVICE_TOKEN、SPRING_DATASOURCE_URL / _USERNAME / _PASSWORD | — | 服务间鉴权令牌;数据库连接,指向 yiyi_storage 库 |
STORAGE_MOUNT_ENABLED | true | FUSE 挂载功能总开关。单机版固定关闭该能力,且不给聚合容器 /dev/fuse、SYS_ADMIN 或 privileged |
TMDB_BEARER_TOKEN | — | TMDB 读取令牌,务必覆盖成自己的 key |
必须用带前缀的真实变量名,短名不生效
常被写成短名(SPOOL_DIR、DISK_CACHE_ENABLED、DISK_CACHE_DIR 等)。 占位符是带前缀的全名,写短名不会被读取。
多台 storage 都留空 YIYI_NODE_ID 会互相顶掉
留空时所有实例都会注册成同一个兜底节点 ID,在注册中心里互相顶掉心跳, 表现为「节点时在线时离线」。一键安装脚本会注入该节点的 YIYI_NODE_ID; 手工部署或复制节点目录时必须显式设置。手填格式:以 node- 开头, 后接 3–60 位字母、数字、下划线或短横线。
节点安装 / 升级脚本专用变量
只在节点机上脚本执行期间生效,用 export 后重跑脚本:
| 变量 | 作用 |
|---|---|
YIYI_NODE_HOST | 手动指定节点对外地址,跳过公网探测 |
YIYI_RESTRICT_SOURCE=1 | 防火墙放行收紧为只允许控制面地址(默认放行所有来源) |
YIYI_OPEN_PORT=0 | 跳过本机防火墙配置 |
YIYI_PG_AUTO=1 / YIYI_PG_PWD | 静默在节点本机安装 PostgreSQL 并建 yiyi_storage 库;非交互式运行必需 |
YIYI_LOCAL_DISK_MOUNTS | storage 以 Docker 运行时要透传进容器的宿主机本地磁盘目录 |
五、安全提示
.env权限0600:安装脚本生成与每次回写都会chmod 0600。- 不得公开或提交:
.env、join.env、集群中继私钥、backups/、data/。 - 口令不进命令行参数:
export YIYI_DB_PASSWORD=...会留在 shell 历史里,docker run -e X=<值>会出现在docker inspect与进程列表中。 YIYI_SERVICE_TOKEN全集群一致且不可重新生成:轮换时控制面与全部外部节点 要同时更新并重启。- 首次部署后不要改
YIYI_DB_PASSWORD:bundled模式下它同时是内置 PostgreSQL 的初始化口令,改了会让数据目录里的口令与配置不一致。 - 激活码不经命令行、URL、环境变量或日志传递:首次授权与后续授权状态都在网页里处理。
- 生产环境应为网页入口配置 HTTPS,详见反向代理与域名。