25 KiB
Docker 容器启动处理流程
本文档说明 MoviePilot V3 镜像从 Docker 创建容器到后端进入 ready 状态的完整处理链,覆盖
docker/ 下的控制脚本、更新事务、依赖自愈、浏览器和证书准备、Nginx、Python lifespan、
异常保活与退出清理。
本文基于 v3 分支 2026-09-07 的实现整理。实际行为以当前源码为准。
1. 文件职责
| 文件 | 运行位置与职责 |
|---|---|
docker/Dockerfile |
构建 Python 环境、后端、前端、插件、站点资源和容器控制面;声明 tini 入口与 readiness 健康检查。 |
docker/launcher.sh |
构建时复制为镜像根目录 /entrypoint.sh;以 root 校验、选择并固化本轮启动使用的控制脚本。 |
docker/entrypoint.sh |
真正的容器启动编排器;加载配置,驱动更新、权限、浏览器和证书准备,最后启动 supervisor。 |
docker/backend.sh |
supervisor 托管的后端进程命令,负责工作目录、权限和 Python 进程。 |
docker/supervisord.conf |
容器内 supervisor 配置,同时托管 Nginx 和后端。 |
docker/update.sh |
被 entrypoint.sh source;处理未完成更新恢复、Dev 更新、依赖同步和载荷事务,不再安装 Release 程序包。 |
docker/update-worker.sh |
由 Supervisor 以 root 按需运行;将已确认的 Release/资源制品替换到 Docker 程序目录,然后请求入口重新加载新代码。 |
docker/browser.sh |
被 entrypoint.sh source;选择持久化 CloakBrowser 缓存、校正权限并按需安装浏览器内核。 |
docker/cert.sh |
被 entrypoint.sh source;校验证书、按需安装 acme.sh、签发证书并配置续期任务。 |
docker/nginx.template.conf |
由环境变量渲染为 /etc/nginx/nginx.conf,提供前端静态文件、API 和 SSE 反向代理。 |
docker/nginx.common.conf |
HTTP/HTTPS server 共用的前端、API、SSE 和静态资源规则。 |
2. 总体调用链
Docker
-> tini -g
-> /entrypoint.sh # 镜像内置 launcher.sh
-> 校验并选择控制脚本代际
-> /run/moviepilot/control/<sha256>/entrypoint.sh
-> 加载 /config/app.env
-> 渲染 Nginx 配置
-> source update.sh
-> 恢复未完成更新
-> 仅执行 Dev 更新
-> 必要时用更新后的控制脚本重新 exec 一次
-> source browser.sh
-> 映射 PUID/PGID
-> 检查并按需恢复 Python 运行依赖
-> 校正目录和缓存权限
-> 准备 CloakBrowser 内核
-> source cert.sh
-> 启动前端 Nginx
-> supervisord
-> Nginx
-> gosu moviepilot python3 app/main.py
-> 按需启动 root update-worker.sh 安装已确认 Release/资源制品
-> Uvicorn/FastAPI lifespan
-> 数据库迁移和全部生命周期组件
-> /health/ready 返回 200
镜像的 ENTRYPOINT 为:
/usr/bin/tini -g -- /entrypoint.sh
tini -g 负责回收子进程并把停止信号发送给整个进程组。根目录 /entrypoint.sh 不是业务
entrypoint.sh,而是构建时从 launcher.sh 复制出的最小可信启动器。
3. 控制脚本可信选择
3.1 为什么不直接执行 /app/docker/entrypoint.sh
Docker 的 Dev 更新和 root 更新 worker 都可能整体替换 /app。如果当前 Shell 正在从 /app/docker 继续
source 其他脚本,可能出现同一次启动混用新旧脚本的情况。因此 launcher 会先选择完整的一代控制脚本,
再复制到只属于本轮启动的运行时快照目录。
候选目录:
| 优先级 | 目录 | 用途 |
|---|---|---|
| 1 | /app/docker |
当前源码携带的控制脚本。 |
| 特殊恢复 | /app.__update_previous__/docker |
更新停留在 prepared 且旧代完整可信时,用旧控制脚本恢复事务。 |
| 兜底 | /usr/local/lib/moviepilot/control |
镜像构建时固化的控制脚本,不随 /app 更新。 |
3.2 信任检查
source_bundle_is_trusted() 对源码控制目录执行以下检查:
- 目录及其上级路径不能是符号链接。
- 目录及其上级路径必须归 root 所有,且 group/other 不可写。
- 目录下所有
.sh都必须是普通文件,不能是符号链接。 - 必须至少包含
entrypoint.sh、update.sh、browser.sh、cert.sh。 - 所有脚本必须通过
bash -n。 - 按文件名排序后计算每个脚本的 SHA-256,再计算整组 manifest 的 SHA-256 作为代际编号。
通过检查的脚本会复制到:
/run/moviepilot/control/<generation>/
快照目录权限为 0700,脚本权限为 0500。launcher 导出 MP_CONTROL_DIR 和
MP_CONTROL_GENERATION 后,exec 快照中的 entrypoint.sh。
如果源码脚本不可信或快照失败,会回退镜像内置脚本;镜像内置脚本自身也必须通过完整性和语法检查, 否则容器拒绝启动。
3.3 更新恢复时的代际选择
/config/temp/__update_pending__ 的值会影响 launcher:
| 状态 | 控制脚本选择原则 |
|---|---|
prepared |
优先使用可信的旧代 /app.__update_previous__/docker;旧代不存在时继续检查当前源码。 |
dependencies / blocked |
不使用旧代控制脚本,避免数据库或当前载荷已经前进后执行缺少新迁移的旧逻辑。 |
committed 或无标记 |
使用当前可信源码,失败时回退镜像内置版本。 |
4. 配置加载和 Nginx 渲染
4.1 基础环境
业务 entrypoint.sh 首先设置:
VENV_PATH默认/opt/venv,并前置到PATH;UV_BIN默认/usr/local/bin/uv;CONFIG_DIR默认/config;PACKAGE_CACHE_ROOT默认/config/.cache;UV_CACHE_DIR默认/config/.cache/uv。
4.2 app.env 优先级
脚本解析 ${CONFIG_DIR}/app.env,配置优先级为:
容器进程环境变量(包括显式空字符串)
> /config/app.env
> 脚本内置默认值
普通变量只加载脚本白名单中的启动配置;ACME_ENV_* 变量额外透传给证书流程。app.env 使用 Python
端 set_key(..., quote_mode="always") 对应的单引号格式,未按规范包裹的值只按字面量解析并输出告警。
4.3 Nginx 配置
render_nginx_config() 使用一次 envsubst 生成 /etc/nginx/nginx.conf:
- HTTP 默认监听
NGINX_PORT=3000; - 后端 upstream 默认指向
127.0.0.1:3001; ENABLE_SSL=true时追加 HTTPS server,证书固定读取/config/certs/latest/;/服务/public下的前端文件;/api、SSE 和 CookieCloud 路径转发到后端;- Service Worker、Manifest、普通静态资源分别使用适合更新语义的缓存策略。
5. 启动前更新处理
entrypoint.sh 在 / 目录 source 当前控制快照中的 update.sh。脚本只定义函数和初始化更新状态,
随后由 entrypoint 按顺序调用恢复与更新入口。
5.1 一次性 Dev 更新
如果存在:
/config/temp/moviepilot.pending_dev_update
entrypoint 会删除该标记,并只在本次启动中把 MOVIEPILOT_UPDATE_DEV 临时设为 true。更新阶段结束后
恢复原值,避免把一次性操作变成永久自动更新。
5.2 未完成更新恢复
更新事务使用以下目录:
/app.__update_previous__
/public.__update_previous__
/config/temp/__update_pending__
状态含义与启动处理:
| 状态 | 含义 | 下次启动处理 |
|---|---|---|
prepared |
新载荷已准备,事务开始,但尚未确认依赖阶段或提交。 | 恢复旧载荷并清理事务;没有备份时按当前完整载荷结束未完成事务。 |
dependencies |
正在同步新清单对应的共享虚拟环境。 | 当前 /app、/public 完整时保留当前载荷,改记 blocked,交给启动前依赖自愈;载荷不完整时恢复旧备份。 |
blocked |
已决定保留当前载荷,等待依赖自愈。 | 继续保留当前载荷;依赖自愈成功后清理旧备份和事务标记。 |
committed |
新载荷已切换完成,只剩旧备份清理。 | 清理旧备份并删除事务标记。 |
依赖阶段不能盲目回退旧 /app:数据库可能已经由当前程序迁移到新 revision,旧程序未必包含对应
Alembic migration。保留当前载荷并恢复其依赖,可以避免形成“新数据库 + 旧源码”的不可启动组合。
5.3 已准备的 Release/资源更新
稳定版更新不在容器启动时联网检查 GitHub Release,也不在 update.sh 中比较版本号或替换程序。
后台更新服务负责下载和校验制品;用户确认安装后生成:
/config/temp/moviepilot-update/prepared.json
/config/temp/moviepilot-update/install.json
/config/temp/moviepilot-update/state.json
随后 SystemHelper 请求 Supervisor 启动 root 更新 worker,处理顺序:
- root worker 识别
application、resources目标。 - 校验后端、前端和资源文件存在且 SHA-256 一致。
- 应用更新时解压后端和前端到临时目录,保留当前插件运行目录和 V3 站点资源。
- 同时包含资源目标时,把已准备资源写入新后端的
app/application/site/。 - 只有资源目标时,使用临时目录和备份目录原子替换当前源码携带的资源文件。
- 后端依赖清单变化时,由 root worker 使用共享虚拟环境同步锁定依赖。
- 源码和资源替换完成后消费下载清单,写入重启标记并关闭 Supervisor;外层入口重新执行 launcher,加载新代码。
- 校验、依赖或替换失败时不关闭当前服务,写入
state.json的可重试失败状态。
如果 worker 尚未启动就发生外部容器重启,入口会在启动 Supervisor 前调用同一个 root 安装器兜底消费
install.json,成功后重新执行 launcher;这条恢复路径也不经过 update.sh。
因此,制品下载完成后仍保留用户确认安装这一安全边界;确认后先替换 Docker 中的程序目录,重启只负责加载已经落盘的新代码。
5.4 Dev 自动更新
仅当 MOVIEPILOT_UPDATE_DEV=true 时(首次升级兼容尚未迁移且未配置新开关的旧 MOVIEPILOT_AUTO_UPDATE=dev),启动脚本会联网获取 v3 分支源码和最新 V3 前端 Release。
GitHub 访问按 GITHUB_PROXY、PROXY_HOST、直连顺序选择;包索引按 PIP_PROXY、PROXY_HOST、
直连顺序选择。
后端或前端下载失败时不替换当前载荷。资源下载失败时优先复用当前资源;没有可用旧资源才终止更新。
5.5 载荷切换事务
Release root worker 的应用更新提交顺序为:
- 后台下载后,在 worker 中解压并验证后端和前端。
- 暂存插件和站点资源。
- 写入
prepared。 - 依赖清单变化时写入
dependencies,再同步临时后端声明的依赖。 - 把当前
/app、/public移到旧代备份。 - 把临时
App、dist移到/app、/public。 - 写入
committed。 - 删除旧代备份和事务标记。
Dev 更新仍由 update.sh 使用同一组事务标记处理;非 Dev 的制品替换只在
app.adapters.system.update.SystemUpdateManager 和 docker/update-worker.sh 中执行。
依赖同步固定使用当前虚拟环境解释器,并执行等价于:
uv sync --project <project> --locked --inexact --no-dev --no-install-project \
--python /opt/venv/bin/python3 --no-default-groups --group <runtime-profile>
runtime-profile 由 app.runtime.dependencies.profile 根据标准 CPython 或 free-threaded CPython 选择。
回滚历史载荷时仍保留旧 app/runtime/dependencies.py 选择器兼容,防止旧快照无法恢复依赖。
5.6 控制脚本更新后重入
Release 或 Dev 应用更新成功后,entrypoint 通过根目录 launcher 的 --source-generation 重新计算 /app/docker 代际。
如果新代际与当前 MP_CONTROL_GENERATION 不同,会:
exec /entrypoint.sh --post-update-reexec
launcher 设置“更新已完成”和“已经重入”标志,新 entrypoint 不会重复安装更新。单次启动只允许重入一次; 如果控制脚本再次变化,会终止启动以避免无限循环。
6. 用户、依赖、浏览器和文件权限
6.1 运行用户映射
entrypoint 使用 PUID、PGID 修改镜像内 moviepilot 用户和组。后端、浏览器安装及 doctor 默认通过
gosu moviepilot:moviepilot 执行;Release 更新 worker 明确以 root 运行来替换 root 所有的 /app 和
/public,不会把运行权限提升给后端;START_NOGOSU=true 仅用于不降权的特殊运行场景。即使 PUID/PGID
设置为非 0,内置重启仍然可用,因为 Supervisor socket 会使用映射后的 moviepilot 组权限;但容器入口
本身必须以 root 启动,不能额外使用 Docker 的 --user 覆盖入口用户。
6.2 后端依赖自愈
启动后端前先执行轻量探针:
/opt/venv/bin/python3 -m app.doctor.dependencies
探针检查 Web 栈、中文分词和转换等启动关键能力。成功时不会执行 uv sync;失败时才选择包源并对
当前 /app 执行锁定依赖同步,随后再次探测。
包源不可用、同步失败或二次探测失败时,不再拉起后端,而是进入 Docker 诊断保活流程。
6.3 CloakBrowser 缓存
缓存目录选择顺序:
- 显式绝对路径
CLOAKBROWSER_CACHE_DIR; - 已可用的
/config/.browser/cloakbrowser; - 已可用或单独挂载的历史
${HOME}/.cloakbrowser; - 新安装默认
/config/.browser/cloakbrowser。
显式目录不能是 /、CONFIG_DIR 或 HOME 本身。脚本先确认目录可由 moviepilot 读写,再用
cloakbrowser.binary_info() 判断内核是否可执行;缺失时以 moviepilot 用户安装,失败只告警,首次实际
使用浏览器时仍可重试。
6.4 权限校正
默认启动避免递归扫描大体积浏览器缓存,只处理缓存根和直接子项。主要处理:
- V3 站点资源目录;
- 插件运行目录根;
HOME和CONFIG_DIR下除浏览器缓存外的内容;- 配置目录外的自定义 uv 缓存;
- Nginx 运行和日志目录;
/etc/hosts与/tmp。
MOVIEPILOT_FORCE_CHOWN=true 才会递归修复 /app、/public 和浏览器缓存。修复 /app 时会保留
/app/docker 为 root 所有且不可由 group/other 写入,保证下次 launcher 仍可信任源码控制脚本。
7. 证书与前置服务
7.1 证书处理
cert.sh 临时启用 errexit 和 pipefail,结束后恢复调用方原有 Shell 选项。
| 配置 | 行为 |
|---|---|
ENABLE_SSL=false |
跳过证书处理。 |
ENABLE_SSL=true、AUTO_ISSUE_CERT=false |
要求 /config/certs/latest/fullchain.pem 和 privkey.pem 已存在。 |
ENABLE_SSL=true、AUTO_ISSUE_CERT=true |
要求 SSL_DOMAIN 和 DNS_PROVIDER;按需安装 acme.sh、加载 ACME_ENV_*、签发并安装证书。 |
自动签发证书保存到 /config/certs/<domain>/,并维护 /config/certs/latest 符号链接。存在 cron 时,
脚本写入 /etc/cron.d/acme,每天 03:00 执行续期检查。续期任务配置失败不会阻断已有证书启动。
7.2 Nginx 和 supervisor
证书检查完成后,entrypoint 以前台模式启动 supervisor。supervisor 同时托管 moviepilot-nginx 与
moviepilot-backend,两者异常退出时自动拉起;显式安装更新时还会按需启动 root worker。控制 socket 位于 /run/moviepilot/supervisor.sock,权限为
root:moviepilot、0770,后端运行用户可访问;控制面同时启用认证,密码默认在每次容器启动时随机生成,
不写入配置卷。supervisor 本身显式以 root 运行以管理 Nginx,后端仍由 backend.sh 降权为
moviepilot;镜像不再挂载或代理 Docker Socket。
8. Python 后端启动
entrypoint 设置 UMASK 后,以后台进程启动:
gosu moviepilot:moviepilot /opt/venv/bin/python3 app/main.py
app/main.py 的主要步骤:
- 修正直接执行脚本时的
sys.path,只让项目根目录作为应用导入入口。 - 设置进程标题并读取运行配置。
- 校验进程拓扑;全功能模式要求单 worker,安全模式允许降级拓扑。
- 注册 SIGINT/SIGTERM 处理器。
- 生产单进程模式创建
MoviePilotServer并运行 Uvicorn。 - FastAPI 应用通过
app.factory.create_app()安装公开健康探针、中间件、异常处理和 lifespan。
8.1 FastAPI lifespan 启动顺序
生命周期组件按 start_order 串行启动:
| 顺序 | 组件 | 关键处理 |
|---|---|---|
| 1 | 文件日志 | 创建本次 lifespan 独占的文件日志 writer。 |
| 5 | 后台任务登记器 | 建立统一的后台任务所有权和关停入口。 |
| 10 | 数据库准备 | 校验迁移 lineage,按需备份,执行建表/Alembic upgrade,再确认唯一 head。 |
| 20 | HTTP 基础能力 | 配置默认 User-Agent 和共享异步传输。 |
| 25 | 站点访问端口 | 注入站点访问所需的网络、浏览器和 OCR 适配。 |
| 26 | Chain 外部端口 | 注入 Chain 使用的外部系统能力。 |
| 27 | Chain 网络端口 | 注入同步网络和系统适配。 |
| 30 | 领域依赖装配 | 注入识别规则、DNS、系统和 Rust 能力。 |
| 40 | 数据库引擎预热 | 物化同步与异步数据库引擎。 |
| 50 | 数据库连接预算 | 校验当前部署的连接池预算。 |
| 60 | 路由 | 注册主程序 API 路由。 |
| 65 | 插件运行时装配 | 构造插件市场和插件运行时依赖。 |
| 70 | 模块服务 | 构造唯一 HostRuntime、数据库 worker、配置、Agent/Chain/资源/事件等核心服务。 |
| 72 | 插件服务装配 | 发布插件安装、目录和动态路由服务。 |
| 75 | 消息队列 | 创建共享消息队列。 |
| 80 | 插件备份恢复 | 普通模式下恢复启动前插件备份。 |
| 90 | 插件 | 普通模式下加载插件。 |
| 100 | 定时器 | 普通模式下启动 Scheduler 和 Agent 定时任务。 |
| 110 | 监控器 | 普通模式下启动目录监控。 |
| 120 | 待处理整理回放 | 普通模式下恢复未完成整理任务。 |
| 130 | 命令服务 | 普通模式下注册命令入口。 |
| 140 | 工作流 | 普通模式下启动工作流后台服务。 |
| 150 | 插件同步与启动收尾 | 登记插件同步收尾任务,由 TaskRegistry 统一管理。 |
其中“模块服务”内部还会组装当前 lifespan 唯一的配置、数据库、认证、运行时、Agent、Chain、Outbox、 Transfer、Workflow 和 MoviePilot Server 服务,注册站点资源版本读取器、事件处理器和模块管理器。
MOVIEPILOT_SAFE_MODE=true 时跳过标记为 NORMAL_ONLY 的插件、调度器、监控、命令和工作流等组件,
但数据库、路由、核心模块服务和后台诊断入口仍会启动。
插件安装 journal 的启动恢复按插件逐条处理:单个插件的恢复或事实校验失败会记录日志、保留 journal 供后续重试,并跳过本条恢复,不阻断其他插件和宿主启动;数据库读取或插件恢复服务本身的全局故障仍按 生命周期组件失败处理。
8.2 数据库就绪边界
数据库准备先读取当前 revision 和代码唯一 head:
- revision 不可识别、存在多个 current/head、或 current 不是目标 head 的祖先时直接失败;
- 已标记的旧数据库需要迁移时,先 Alembic upgrade,再按当前元数据补表;
- 新库或未标记旧库先建表,再执行 Alembic;
- 配置允许时,迁移前创建数据库备份;
- 迁移结束后再次验证数据库已经到达当前唯一 head。
只有该阶段完成,应用健康状态才标记 database_ready。
8.3 readiness
所有启用的 fail-fast 启动组件成功后,lifespan 才把应用标记为 ready。插件恢复中的单插件失败已在
组件内部隔离,不会把该组件升级为宿主级启动失败。
Dockerfile 的 HEALTHCHECK 每 30 秒请求 http://127.0.0.1:${PORT}/health/ready:数据库迁移和完整 lifespan 成功后返回 200;启动、
失败或关停阶段返回 503。/health/live 只表示进程和事件循环仍可响应。
9. 异常、重启和退出
9.1 信号退出
容器的 supervisor 接收 SIGINT/SIGTERM 后按顺序停止受管进程:
- 停止前端 Nginx;
- 等待 Python 完成 lifespan 逆序关停;
- supervisor 退出,容器按原退出状态结束。
Python lifespan 会先撤销 readiness,再按组件声明的 stop_order 停止工作流、命令、插件、事件、Agent、
整理任务、模块服务、数据库和日志等资源。启动中途失败时,只清理已经启动或正在启动的组件。
9.2 应用内重启
普通应用重启通过本地 supervisorctl restart all 同时重启 Nginx 和后端。确认安装 Release 时,
SystemHelper 只启动 root moviepilot-update-worker;worker 先替换 /app、/public 或站点资源,
再写入 moviepilot.pending_supervisor_restart 并执行 supervisorctl shutdown。外层 entrypoint 看到标记后
重新执行 launcher,加载新代码。Dev 更新仍通过一次性 Dev 标记关闭 Supervisor,再由 entrypoint 调用
update.sh。这样更新包不会因只重启受管进程而停留在暂存目录;整个过程不访问 Docker API,也不依赖
Docker restart policy。
9.3 异常诊断
后端异常退出由 supervisor 自动拉起;启动前的依赖、更新或迁移失败会直接终止容器启动并保留日志。
10. 关键运行文件
| 路径 | 作用 |
|---|---|
/entrypoint.sh |
镜像内置 launcher。 |
/usr/local/lib/moviepilot/control/ |
镜像构建时固化的控制脚本。 |
/run/moviepilot/control/<generation>/ |
本轮启动执行的只读控制快照。 |
/app |
当前后端源码和插件运行目录。 |
/public |
当前前端静态文件。 |
/config/app.env |
Docker 启动脚本和应用配置。 |
/config/.cache/uv |
默认 uv 持久缓存。 |
/config/.browser/cloakbrowser |
默认 CloakBrowser 持久缓存。 |
/config/temp/__update_pending__ |
载荷切换事务状态。 |
/app.__update_previous__ |
更新前后端备份。 |
/public.__update_previous__ |
更新前前端备份。 |
/config/temp/moviepilot-update/ |
后台下载的 Release/资源包及安装状态。 |
/config/temp/moviepilot.pending_supervisor_restart |
Release worker 已替换程序、等待入口重新加载的标记。 |
/config/temp/moviepilot.pending_dev_update |
单次 Dev 更新请求。 |
/run/moviepilot/supervisor.sock |
容器内 supervisor 控制 socket,权限为 root:moviepilot、0770,并启用本次容器启动的认证凭据。 |
/config/certs/latest/ |
Nginx 使用的稳定证书路径。 |
11. 关键环境变量
| 变量 | 默认值 | 影响 |
|---|---|---|
CONFIG_DIR |
/config |
配置、缓存、更新状态和证书根目录。 |
PUID / PGID |
0 / 0 |
映射 moviepilot 运行用户。 |
UMASK |
000 |
后端进程文件权限掩码。 |
PORT |
3001 |
后端监听和 readiness 端口。 |
NGINX_PORT |
3000 |
HTTP 前端入口。 |
MOVIEPILOT_AUTO_UPDATE |
false |
布尔开关,仅 true 开启后台版本检查和升级提醒;关闭后不检查主程序;AUTO_UPDATE_RESOURCE=true 时仍启用服务且只检查站点资源。稳定版下载及安装需手动确认。旧 dev/release 统一迁移为 true。 |
MOVIEPILOT_UPDATE_DEV |
false |
独立布尔开关,true 触发 update.sh 的启动时 Dev 分支更新;旧 dev 在未显式配置此开关时保留跟踪偏好。 |
MOVIEPILOT_SAFE_MODE |
false |
跳过普通模式专属的插件及后台控制面。 |
MOVIEPILOT_FORCE_CHOWN |
false |
是否执行大范围递归权限修复。 |
PACKAGE_CACHE_ROOT |
/config/.cache |
包管理缓存根目录。 |
UV_CACHE_DIR |
/config/.cache/uv |
uv 缓存目录。 |
PIP_PROXY |
空 | Python 包索引镜像。 |
GITHUB_PROXY |
空 | GitHub 下载 URL 前缀。 |
PROXY_HOST |
空 | GitHub/包命令使用的 HTTP(S) 代理。 |
GITHUB_TOKEN |
空 | Dev 更新访问 GitHub 时的令牌。 |
CLOAKBROWSER_CACHE_DIR |
自动选择 | 浏览器内核缓存位置。 |
ENABLE_SSL |
false |
是否渲染并启用 HTTPS server。 |
AUTO_ISSUE_CERT |
false |
是否自动签发证书。 |
SSL_DOMAIN / SSL_EMAIL / DNS_PROVIDER |
空 | acme.sh 签发参数。 |
12. 维护约束
后续修改 Docker 启动流程时应保持以下边界:
- 控制脚本必须按完整代际执行,不能在同一次启动中直接混用更新前后的
/app/docker/*.sh。 - Release 更新由后台下载、用户确认和 root worker 驱动;
update.sh不得恢复 Release 程序/资源替换、启动时 GitHub Release 查询或 Shell 版本比较。 - 更新载荷与共享虚拟环境必须作为一个可恢复事务处理,不能留下新源码配旧依赖或旧源码配新数据库的混合状态。
- 标准 V3 与 V3t 依赖恢复必须复用
app.runtime.dependencies.profile,不能使用默认组覆盖当前 ABI profile。 - 站点资源只安装到
app/application/site/;历史目录仅用于更新旧载荷时读取兼容资源。 - readiness 只能在数据库 head 校验和完整 lifespan 成功后发布,不能退化为进程存在或普通接口可访问。
- 后端异常保活是诊断机制,不是成功状态;外部编排必须继续以
/health/ready判断可接流量。