在 Fly.io 上部署智能体
将 Flue 智能体部署到 Fly.io。本指南假设你已经有一个正在运行的 Flue 项目。如果你还没有,请先完成快速开始。
Flue 的 Node 目标是一个长期运行的 HTTP 服务器,而非函数。它在进程中持有智能体会话,并通过长连接提供流式响应。在 Fly.io 上,这意味着将其作为长期运行的 Docker 应用运行 — 不是 auto-stop 机器,不是 scale-to-zero 函数。
先决条件
你需要:
- 一个 Fly.io 账户和已安装的
flyctlCLI - 一个正在运行的 Flue 项目(
flue run应该可以工作)
设置
1. 初始化 Fly 应用
从你的 Flue 项目根目录运行:
fly launch
这将创建一个 fly.toml 配置文件。当被问到时:
- 选择一个应用名称(或接受建议的名称)
- 选择一个部署区域
- 当被问到是否设置 Postgres 时,选择是 — 你稍后会需要它
- 当被问到是否设置 Redis 时,选择否(除非你的应用特定需要它)
2. 配置 fly.toml
编辑生成的 fly.toml 以匹配你的 Flue 应用:
app = "your-app-name"
primary_region = "iad"
[build]
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = false
auto_start_machines = true
min_machines_running = 1
[http_service.concurrency]
type = "connections"
hard_limit = 250
soft_limit = 200
[[vm]]
size = "shared-cpu-1x"
memory = "512mb"关键设置:
auto_stop_machines = false:Flue 需要长期运行的进程来持有会话。不要让它自动停止。min_machines_running = 1:始终保持至少一台机器运行以持有会话。internal_port = 8080:匹配你的 Dockerfile 中PORT环境变量设置的端口。
3. 创建 Dockerfile
在项目根目录创建一个 Dockerfile:
# syntax=docker/dockerfile:1
FROM node:22-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npx vite build
FROM node:22-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY package.json package-lock.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
USER node
ENV PORT=8080
EXPOSE 8080
CMD ["node", "dist/server.mjs"]4. 设置密钥
Fly.io 使用密钥来管理敏感环境变量。设置你的模型 provider key:
fly secrets set ANTHROPIC_API_KEY=sk-...
如果你使用 Postgres(推荐),Fly 会自动将 DATABASE_URL 添加到你的应用中。
可选地,设置模型标识符:
fly secrets set MODEL_SPECIFIER=anthropic/claude-sonnet-4-6
5. 设置持久化
没有数据库适配器,Flue 将对话保存在内存中 — 重启时会丢失。添加一个 Postgres 支持的适配器以实现持久化:
import { postgres } from '@flue/postgres';
import { Pool } from 'pg';
// 使用 Fly 提供的 DATABASE_URL 创建连接池
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export default postgres({
query: async (text, params) => (await pool.query(text, params)).rows,
transaction: async (fn) => {
const client = await pool.connect();
try {
await client.query('BEGIN');
const result = await fn(client);
await client.query('COMMIT');
return result;
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
},
close: () => pool.end(),
});如果你在 fly launch 期间设置了 Postgres,连接字符串已经作为 DATABASE_URL 密钥可用。如果没有,添加一个 Postgres 集群:
fly postgres create
fly postgres attach <your-postgres-app>
参见 Postgres 了解完整的自带驱动运行器。
6. 部署
fly deploy
这将构建你的 Docker 镜像并将其部署到 Fly.io。部署完成后,你的智能体将在 https://your-app-name.fly.dev 可用。
7. 测试
curl -X POST 'https://your-app-name.fly.dev/agents/my-agent/demo-1' \
-H "Content-Type: application/json" \
-d '{"kind": "user", "body": "Hello!"}'
扩展
垂直扩展
通过编辑 fly.toml 中的 [[vm]] 部分来增加内存或 CPU:
[[vm]]
size = "shared-cpu-2x"
memory = "1gb"
水平扩展
要运行多台机器:
fly scale count 2
重要:当你水平扩展时,所有机器共享同一个数据库(通过 DATABASE_URL)。然而,每个智能体实例仍必须路由到一个活动所有者 — 不要对同一实例进行轮询。Flue 不提供跨机器的会话亲和性,因此你需要在负载均衡器层处理这个问题。
健康检查
Flue 不会自动生成健康检查端点。在你的 app.ts 中添加一个:
import { createAgentRouter } from '@flue/runtime/routing';
import { Hono } from 'hono';
import { MyAgent } from './agents/my-agent.ts';
const app = new Hono();
app.get('/health', (c) => c.text('ok'));
app.route('/agents/my-agent', createAgentRouter(MyAgent));
export default app;然后更新 fly.toml 添加健康检查:
[http_service]
# ... 其他设置 ...
[[http_service.checks]]
interval = "10s"
timeout = "2s"
grace_period = "5s"
method = "GET"
path = "/health"
流式传输注意事项
Fly.io 支持长连接,这对 Flue 的流式对话至关重要。默认情况下,Fly 的代理在 60 秒不活动后超时。对于长时间运行的流,你可能需要增加这个值:
[http_service]
# ... 其他设置 ...
[http_service.concurrency]
type = "connections"
hard_limit = 250
soft_limit = 200
客户端应使用 Flue Agent SDK 的 wait() 和 observe() 方法来处理流式传输,它们会自动管理重新连接。
日志和监控
查看你的应用日志:
fly logs
在你的应用运行时监控它:
fly status
fly ssh console
参考资料
- Fly.io 文档 — 官方 Fly.io 文档。
- Fly.io Machines — 有关 Machines API 的更多信息。
- Docker 部署 — 底层 Docker 镜像的详细信息。