news 2026/9/14 8:23:34

OmniRoute 部署到 Fly.io:fly.toml 配置、持久卷挂载与 Secrets 管理的完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OmniRoute 部署到 Fly.io:fly.toml 配置、持久卷挂载与 Secrets 管理的完整实战指南

OmniRoute 部署到 Fly.io:fly.toml 配置、持久卷挂载与 Secrets 管理的完整实战指南

【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute

本文基于 OmniRoute 仓库中已经验证通过的 Fly.io 部署配置(docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md 及其中文/葡语翻译版本),系统讲解如何把 OmniRoute 网关部署到 Fly.io:从fly.toml关键配置项、flyctl首次部署与后续发版流程,到DATA_DIRJWT_SECRETSTORAGE_ENCRYPTION_KEY等运行时参数的设置原理。读完本文,你可以独立完成首次部署、理解每类参数的底层用途,并在代码更新或上游同步后安全地滚动发布。

1. 部署目标与运行形态

OmniRoute 在 Fly.io 上的部署采用"本地flyctl直接发布"的方式,复用仓库内现有的 Dockerfile 与 fly.toml,不依赖 Fly 的远程构建扩展:

项目取值
平台Fly.io
部署方式本地flyctl deploy直接发布
运行方式仓库内Dockerfile构建的独立(standalone)镜像 +fly.toml
数据持久化Fly Volume 挂载到/data
应用名omniroute
访问地址https://omniroute.fly.dev/(以当前项目实测为准)

运行入口由fly.toml[processes]段指定:

[processes] app = 'node run-standalone.mjs'

从源码结构看,这个入口在容器内执行 scripts/dev/run-standalone.mjs。它先调用bootstrapEnv()完成环境变量分层合并与密钥自举,再把PORT、堆大小等运行时参数注入子进程,最后优先选择带 WebSocket 支持的server-ws.mjs(用于授权中间件的 peer-IP 标记),否则回退到 Next.js standalone 的server.js

2. 当前仓库fly.toml的关键配置

当前仓库中的 fly.toml 确认包含以下关键项(比部署文档中的摘录更完整):

app = 'omniroute' primary_region = 'sin' [build] [processes] app = 'node run-standalone.mjs' [[mounts]] source = 'data' destination = '/data' auto_extend_size_threshold = 80 auto_extend_size_increment = '1GB' auto_extend_size_limit = '10GB' [http_service] internal_port = 20128 force_https = true auto_stop_machines = 'stop' auto_start_machines = true min_machines_running = 1 processes = ['app'] [[vm]] memory = '1gb' cpu_kind = 'shared' cpus = 1 memory_mb = 1024 [env] TZ = "Asia/Shanghai" # Bind to all interfaces for Fly runtime networking. HOST = "0.0.0.0" HOSTNAME = "0.0.0.0" BIND = "0.0.0.0"

各配置项的作用:

  • app = 'omniroute':决定部署到哪个 Fly 应用。控制台里查看的必须是对应的应用名,切勿与旧名(如oroute)混淆。
  • primary_region = 'sin':主区域,新机器优先在该区域创建。
  • [[mounts]]destination = '/data'决定持久卷挂载目录。auto_extend_size_threshold = 80表示卷使用率达到 80% 时自动扩容,每次加1GB,上限10GB。本项目必须让DATA_DIR=/data,否则数据库和密钥会写到容器临时目录,重建后丢失。
  • [http_service]internal_port = 20128:与 Dockerfile 中ENV PORT=20128EXPOSE 20128对应,Fly 边缘把 HTTPS 流量转发到容器内的该端口。
  • auto_stop_machines/auto_start_machines/min_machines_running = 1:空闲停机但保留一台常驻机器的策略,兼顾成本与可用性。
  • [[vm]]:1GB 内存、1 vCPU 共享型。从源码结构看,运行时堆大小由 Dockerfile 中的OMNIROUTE_MEMORY_MB=1024控制(--max-old-space-size),因此 1GB 机器规格与该默认值匹配。
  • [env]中的HOST/HOSTNAME/BIND = "0.0.0.0":Fly 运行时网络要求进程绑定所有接口;TZ用于统一日志时区。

3. 必备工具:安装与登录 Fly CLI

3.1 安装 Fly CLI

Windows PowerShell:

pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"

如果安装脚本在当前环境失败,也可以手动下载flyctl二进制并放到PATH中。

3.2 登录并检查状态

flyctl auth login flyctl auth whoami flyctl version

4. 首次部署当前项目

4.1 获取代码并进入目录

git clone <你的仓库地址> cd OmniRoute

适用前提:本文中的部署流程针对 OmniRoute 仓库根目录,要求根目录存在Dockerfilefly.tomlflyctl deploy会在本地构建镜像后推送发布。

4.2 确认应用名

打开fly.toml,重点看这一行:

app = 'omniroute'

如果你准备部署到自己的新应用,可改成全局唯一名称,例如:

app = 'omniroute-yourname'

注意:控制台里要看的是与fly.tomlapp一致的应用;如果以前用过别的名字(例如oroute),不要和omniroute混淆。

4.3 创建应用

如果该应用尚不存在:

flyctl apps create omniroute

如果已改成别的应用名,把omniroute替换成你的名字。

4.4 首次部署

flyctl deploy

5. 必配参数与运行时自举机制

本项目在 Fly.io 上建议至少配置以下参数,它们已经验证可用于当前omniroute应用:

  • API_KEY_SECRET
  • DATA_DIR
  • JWT_SECRET
  • MACHINE_ID_SALT
  • NEXT_PUBLIC_BASE_URL
  • STORAGE_ENCRYPTION_KEY

5.1 这些参数在代码中如何使用

仓库的启动链路对理解"为什么必须配置它们"很有帮助:

  • 容器启动时,run-standalone.mjs调用的bootstrapEnv()(实现在 scripts/build/bootstrap-env.mjs)会做三层合并:已持久化的<DATA_DIR>/server.env→ 项目.env→ 进程环境变量(空值会被过滤,避免docker run -e KEY=覆盖真实值)。
  • 如果JWT_SECRETSTORAGE_ENCRYPTION_KEYAPI_KEY_SECRET缺失,自举逻辑会用randomBytes自动生成并写入<DATA_DIR>/server.env,日志输出[bootstrap] Secrets persisted to: /data/server.env
  • 关键约束:如果<DATA_DIR>/storage.sqlite中已存在enc:v1:*加密凭证,而STORAGE_ENCRYPTION_KEY缺失,自举会直接抛错拒绝启动(防止新密钥无法解密旧凭证)。所以在 Fly 这类无状态重建频繁的环境中,把这三个密钥显式放入 Secrets 是更稳妥的做法,而不是依赖自动生成。
  • INITIAL_PASSWORD未设置时,自举会打印警告并回退到默认密码CHANGEME,部署后应尽快在系统设置中修改登录密码。

5.2 关于INITIAL_PASSWORD

当前项目没有设置INITIAL_PASSWORD,因为本次部署按需求不使用它。如果不设置:

  • 启动日志会提示默认密码是CHANGEME
  • 部署后应尽快在系统设置中修改登录密码。

如果你希望无人值守初始化后台密码,也可以后续补:

flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute

6. 推荐参数说明

6.1 Secrets 中设置

建议放入 Fly Secrets:

变量名是否推荐说明
API_KEY_SECRET必需API Key 生成与校验使用
JWT_SECRET必需登录态和 JWT 签名使用
STORAGE_ENCRYPTION_KEY强烈推荐加密存储敏感连接信息(provider_connections中的enc:v1:*字段)
MACHINE_ID_SALT推荐生成稳定机器标识
INITIAL_PASSWORD可选首次部署时直接指定后台初始密码
OAuth/API 私密凭证按需各类外部平台鉴权配置

6.2 当前项目推荐值

变量名推荐值
DATA_DIR/data
NEXT_PUBLIC_BASE_URLhttps://omniroute.fly.dev

说明:

  • DATA_DIR=/data非常关键,必须与fly.toml[[mounts]]的挂载点一致。注意 Dockerfile 中 runner 阶段的镜像默认值是ENV DATA_DIR=/app/data(配合docker-compose卷),部署到 Fly 时必须用环境变量覆盖为/data,这正是"数据没有持久化"这类问题的常见根因。
  • NEXT_PUBLIC_BASE_URL用于调度器和前端回调等场景。

7. 一键设置参数

下面命令会生成安全随机值,并把当前项目需要的参数一次性写入 Fly Secrets:

  • 不包含INITIAL_PASSWORD
  • 适用于当前项目omniroute
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() $storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower() flyctl secrets set ` API_KEY_SECRET=$apiKeySecret ` JWT_SECRET=$jwtSecret ` MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey ` DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev ` -a omniroute

从源码看各长度的对应关系:JWT_SECRET生成 64 字节十六进制(与自举中randomBytes(64)对齐),API_KEY_SECRETSTORAGE_ENCRYPTION_KEYMACHINE_ID_SALT各 32 字节,与自举逻辑生成的长度一致,保证替换后兼容既有enc:v1:数据。

8. 查看当前参数

flyctl secrets list -a omniroute

如果控制台Secrets页面没有显示你期待的变量,先检查:

  • 看的应用是不是omniroute
  • fly.tomlapp是否和控制台应用一致

9. 后续更新发布

代码有更新后,发布步骤很简单:

git pull flyctl deploy

如果只更新参数,不改代码:

flyctl secrets set KEY=value -a omniroute

Fly 会自动滚动更新机器。

9.1 跟踪原仓库更新并保留 fork 的fly.toml

如果当前仓库是 fork,并且你要同步上游https://github.com/diegosouzapw/OmniRoute的更新,推荐按下面流程执行。

先确认远程:

git remote -v

应至少包含:

  • origin指向你自己的 fork
  • upstream指向原仓库

如果没有upstream,先添加:

git remote add upstream https://github.com/diegosouzapw/OmniRoute.git

同步上游前,先抓取最新提交和标签:

git fetch upstream --tags

查看当前版本和上游标签:

git describe --tags --always git show --no-patch --oneline v3.4.7

如果你想合并上游最新main,并强制保留 fork 当前的fly.toml,可按下面流程执行:

git merge upstream/main git checkout HEAD~1 -- fly.toml git add -- fly.toml git commit -m "chore(deploy): keep fork fly.toml" git push origin main

说明:

  • git merge upstream/main用于同步原仓库最新代码;
  • git checkout HEAD~1 -- fly.toml用于恢复合并前你 fork 自己的fly.toml
  • 如果上游没有改fly.toml,这一步不会带来额外差异;
  • 如果上游改了fly.toml,这一步能确保 Fly 应用名、挂载卷、区域等 fork 自定义部署配置不被覆盖。

如果你明确只想对齐某个发布标签,例如v3.4.7,也可以先确认标签是否已经包含在upstream/main

git merge-base --is-ancestor v3.4.7 upstream/main

返回成功表示upstream/main已经包含该版本,直接合并upstream/main即可。

9.2 同步上游后的标准发布顺序

同步原仓库完成后,推荐按下面顺序发布:

  1. git fetch upstream --tags
  2. git merge upstream/main
  3. 恢复 fork 的fly.toml
  4. git push origin main
  5. flyctl deploy
  6. flyctl status -a omniroute
  7. flyctl logs --no-tail -a omniroute

这就是当前项目升级到v3.4.7时使用的实际流程。

10. 发布后检查

10.1 查看应用状态

flyctl status -a omniroute

10.2 查看启动日志

flyctl logs --no-tail -a omniroute

10.3 检查网站可访问

try { (Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode } catch { if ($_.Exception.Response) { $_.Exception.Response.StatusCode.value__ } else { throw } }

返回200说明站点已正常响应。此外,镜像内置健康检查(Dockerfile 中HEALTHCHECK调用node healthcheck.mjs,即 scripts/dev/healthcheck.mjs),可作为容器存活信号。

11. 成功标志:日志里验证持久化是否生效

部署成功后,日志里应看到类似内容:

[bootstrap] Secrets persisted to: /data/server.env [DB] SQLite database ready: /data/storage.sqlite

这两行日志都能在源码中找到出处:

  • 第一行由 scripts/build/bootstrap-env.mjs 在密钥写入<DATA_DIR>/server.env后打印,说明运行时密钥落到了持久卷;
  • 第二行由 src/lib/db/core.ts 在打开数据库成功后打印([DB] SQLite database ready: ${sqliteFile}),说明数据库写入持久卷。

如果你看到的是/app/data/...,说明DATA_DIR没配对(回退到了 Dockerfile 的镜像默认值/app/data),需要立即通过flyctl secrets set DATA_DIR=/data -a omniroute修正并重新部署。

12. 常见问题

12.1Secrets页面是空的

通常有两种原因:

  • 你还没执行flyctl secrets set
  • 你打开的是另一个应用,例如oroute,不是omniroute

12.2flyctl deployapp not found

先创建应用:

flyctl apps create omniroute

12.3fly.toml解析失败

重点检查:

  • 注释里是否有乱码字符
  • TOML 引号和缩进是否正确

12.4 数据没有持久化

检查以下两点:

  • fly.toml中是否存在destination = '/data'
  • DATA_DIR是否设置为/data(注意 Docker 镜像默认DATA_DIR=/app/data,必须显式覆盖)

另外,Dockerfile 的ENTRYPOINT是 scripts/check-permissions.sh,会在挂载卷属主不正确时发出警告,检查日志时也可留意该输出。

12.5 不设置INITIAL_PASSWORD是否能跑

可以运行,但会回退到默认CHANGEME。生产环境建议尽快修改后台密码。

13. 新项目复用建议

如果以后是新项目照着这份文档部署,最少改这几项:

  1. 修改fly.toml里的app
  2. 修改NEXT_PUBLIC_BASE_URL
  3. 保持DATA_DIR=/data
  4. 重新生成API_KEY_SECRETJWT_SECRETMACHINE_ID_SALTSTORAGE_ENCRYPTION_KEY
  5. 首次部署后检查日志是否写入/data

不要直接复用旧项目的密钥。特别是STORAGE_ENCRYPTION_KEY:一旦storage.sqlite中存在enc:v1:*凭证,换用新密钥将导致这些数据永久无法解密(自举逻辑会拒绝在新密钥下继续运行),迁移时必须沿用原密钥。

14. 当前项目的最小发布清单

当前项目后续最常用的命令如下:

flyctl auth whoami flyctl status -a omniroute flyctl secrets list -a omniroute flyctl deploy flyctl logs --no-tail -a omniroute

如果只是正常发版,核心就是:

flyctl deploy

如果是新环境首次部署,核心就是:

  1. flyctl auth login
  2. flyctl apps create omniroute
  3. flyctl secrets set ... -a omniroute
  4. flyctl deploy
  5. flyctl logs --no-tail -a omniroute

延伸阅读:本文的英文版原文位于 docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md,当前版本为该文档的多语言翻译之一(docs/i18n/pt-BR/docs/ops/FLY_IO_DEPLOYMENT_GUIDE.md)。如需了解 SQLite 运行时细节与数据目录约定,可参考 docs/ops/SQLITE_RUNTIME.md;容器本地部署方式见 docs/guides/DOCKER_GUIDE.md。

【免费下载链接】OmniRouteNever stop coding. Free MIT AI gateway: one endpoint, 352 providers (150+ free), 1200+ models Kimi, Claude, GPT, Gemini, GLM, DeepSeek, MiniMax. Works with Claude Code, Codex, Cursor, OpenCode, Cline & Copilot. Quota-aware auto-fallback, RTK+Caveman compression saves 15-95% tokens, MCP/A2A, Desktop/PWA. Built by 550+ contributors项目地址: https://gitcode.com/GitHub_Trending/om/OmniRoute

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 8:22:18

远程办公真·免安装:ToDesk、向日葵、UU远程实战选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 8:13:34

MSO-VMD-SVM算法在工业故障诊断中的应用与优化

1. 项目概述&#xff1a;MSO-VMD-SVM故障诊断算法框架在工业设备故障诊断领域&#xff0c;信号分解与模式识别的结合一直是研究热点。2025年海市蜃楼&#xff08;MSO&#xff09;算法提出了一种创新的技术路线&#xff1a;通过改进的变分模态分解&#xff08;VMD&#xff09;结…

作者头像 李华
网站建设 2026/9/14 8:09:52

SEO优化全攻略:从技术到内容的完整检查清单

1. SEO优化检查清单概述 SEO&#xff08;Search Engine Optimization&#xff09;优化是提升网站在搜索引擎自然排名的一系列技术手段和策略。作为从业十年的SEO专家&#xff0c;我总结出一套完整的检查清单&#xff0c;帮助网站从技术架构到内容质量全面优化。 SEO优化的核心…

作者头像 李华
网站建设 2026/9/14 8:02:55

DeskcommCRM全解析:从核心模块到私有化部署实践

DeskcommCRM 这个名字我第一次看到的时候&#xff0c;以为是某个团队内部用的客服平台代号&#xff0c;后来真正接触下来才发现&#xff0c;它本质上是一套把“桌面工作台”和“客户沟通”深度绑定的客户关系管理系统。简单说&#xff0c;它不只是一本电子通讯录&#xff0c;而…

作者头像 李华