mcpField
F
fly-io

fly-io

github.com/fellowship-dev云与 DevOps3200 次安装2 周前更新
代码仓库

关于 fly-io

Fly.io 技能为应用部署和运维提供操作指南,面向使用 flyctl 管理应用及 PostgreSQL 的团队。内容覆盖配置、部署、CI/CD、监控、扩缩容和数据库备份恢复。

主要功能

  1. 01应用初始化与 fly.toml 配置
  2. 02环境变量和密钥管理
  3. 03PostgreSQL 创建、连接与备份恢复
  4. 04部署及 GitHub Actions CI/CD
  5. 05日志、健康检查与故障排查
  6. 06资源扩缩容和区域管理

适用场景

  1. 01将应用首次部署到 Fly.io
  2. 02为 Fly.io 应用配置 PostgreSQL
  3. 03设置 GitHub Actions 自动部署
  4. 04排查部署、数据库连接或应用故障

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fellowship-dev/dogfooded-skills --skill fly-io

安装后在 Claude Code 中输入/fly-io确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples.md
README.md
reference.md
templates/
deployment-checklist.md
fly.toml.template
github-actions-workflow.yml

详细介绍

Fly.io

此技能为将应用部署到 Fly.io 提供全面指导,包括初始设置、数据库管理、CI/CD 集成和生产环境运维。

适用场景

在处理以下事项时,此技能会自动启用:

  • Fly.io 专属任务(“fly.io”“deploy to fly”“fly.io setup”“flyctl”)
  • Fly.io 配置(“fly.toml”“fly app”“fly launch”)
  • Fly.io 数据库操作(“fly postgres”“fly pg”)
  • Fly.io 环境管理(“fly secrets”“fly env”)
  • Fly.io 监控(“fly logs”“fly status”“fly dashboard”)
  • Fly.io GitHub Actions(“fly deploy github action”“flyctl in CI/CD”)

核心原则

  1. 安全第一:始终加密敏感数据,绝不提交未加密的密钥
  2. 数据库安全:通过代理访问数据库,并定期备份
  3. 环境隔离:分离开发、预发布和生产环境的配置
  4. 成本意识:优化资源分配,定期监控用量
  5. 自动化:利用 CI/CD 实现一致、可重复的部署
  6. 监控:实施全面的日志记录和运行状况检查

前提条件

开始部署到 Fly.io 之前:

  1. Fly.io 账号:已激活并绑定信用卡的账号(PostgreSQL 所需)
  2. CLI 安装:已安装并完成身份验证的 flyctl 命令行工具
  3. 环境变量:已准备好项目专属配置
  4. 应用就绪:应用已配置为可部署到生产环境

说明

1. 初始设置和身份验证

安装 Fly.io CLI:

# Standard installation
curl -L https://fly.io/install.sh | sh

# Add to PATH (adjust based on your environment)
export FLYCTL_INSTALL="/home/user/.fly"
export PATH="$FLYCTL_INSTALL/bin:$PATH"

# Verify installation
flyctl version

通过 Fly.io 进行身份验证:

flyctl auth login

这会打开浏览器进行身份验证。成功登录后,凭据会存储在本地。

2. 环境变量管理

加密以确保安全:

Fly.io 部署应使用加密的环境文件来保护敏感数据:

# Decrypt environment file (requires ENV_PASS variable)
openssl enc -aes-256-cbc -pbkdf2 -salt -d -in .env.enc -out .env -k $ENV_PASS

# After modifying .env, re-encrypt
openssl enc -aes-256-cbc -pbkdf2 -salt -in .env -out .env.enc -k $ENV_PASS

# For production environment
openssl enc -aes-256-cbc -pbkdf2 -salt -in .env -out .env.enc.prod -k $ENV_PASS

重要安全说明:

  • 绝不提交未加密的 .env 文件
  • 妥善保存 ENV_PASS(GitHub secrets、密码管理器)
  • 为预发布和生产环境使用不同的加密密码
  • 如果 .env 尚未添加到 .gitignore,请将其添加
3. 数据库设置(PostgreSQL)

创建 PostgreSQL 数据库:

# Create new PostgreSQL database on Fly.io
flyctl postgres create

# When prompted, use naming convention: {project-name}-db
# Example: myapp-db

数据库创建的重要选项:

  • 选择距离用户最近的区域
  • 选择合适的资源层级(从较小规格开始,再逐步扩展)
  • 记录提供的数据库凭据
  • 数据库名称通常与应用名称相同,并带有 “-db” 后缀

将数据库关联到应用:

# Attach database to your application
flyctl pg attach {project-name}-db -a {project-name}

# If attachment fails, set DATABASE_URL manually
flyctl secrets set DATABASE_URL=postgres://user:pass@host:5432/dbname -a {project-name}

验证数据库连接:

# Check database status
flyctl status -a {project-name}-db

# Test connection via proxy
flyctl proxy 5433 -a {project-name}-db
# In another terminal: psql -h localhost -p 5433 -U {username} -d {dbname}
4. 创建和配置应用

启动新应用:

# Create application (don't deploy yet)
flyctl launch

# Follow prompts:
# - Choose app name (matches ENV_NAME variable)
# - Select region (same as database for best performance)
# - Choose resource allocation
# - Decline immediate deployment (configure first)

配置应用:

运行 flyctl launch 后,检查并自定义 fly.toml:

app = "your-app-name"

[build]
  # Adjust based on your application type

[env]
  PORT = "8080"
  HOST = "::"
  # Add other non-secret environment variables

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0

设置密钥:

# Set individual secrets
flyctl secrets set APP_KEYS="your-app-keys" -a {project-name}
flyctl secrets set API_TOKEN_SALT="your-salt" -a {project-name}

# Import from .env file (ensure it's decrypted first)
flyctl secrets import -a {project-name} < .env
5. 部署工作流

部署前检查清单:

  • 已配置环境变量(生产环境值)
  • 已创建并关联数据库
  • 已检查并自定义 fly.toml
  • 已通过 flyctl secrets 设置密钥
  • 应用可在本地成功构建
  • 依赖项已准备好用于生产环境

首次部署:

# Deploy application
flyctl deploy -a {project-name}

# Monitor deployment
flyctl logs -a {project-name}

# Check status
flyctl status -a {project-name}

部署后验证:

# Open application in browser
flyctl open -a {project-name}

# Check health endpoint
curl https://{project-name}.fly.dev/health

# Review logs for errors
flyctl logs -a {project-name}
6. 域名和 SSL 配置

添加自定义域名:

# Add certificate for custom domain
flyctl certs create yourdomain.com -a {project-name}

# Check certificate status
flyctl certs show yourdomain.com -a {project-name}

DNS 配置:

  1. 将域名的 A/AAAA 记录指向 Fly.io
  2. 等待 DNS 传播
  3. 验证证书签发情况
  4. 将环境变量 APP_URL 更新为自定义域名
  5. 使用更新后的配置重新部署
7. 数据库管理

导出 PostgreSQL 数据库(备份):

# Standard dump format (custom format, compressed)
pg_dump -Fc --no-acl --no-owner -h HOST -U USERNAME -d DATABASE_NAME > dump_file.dump

# Example for local database
pg_dump -Fc --no-acl --no-owner -h localhost -U postgres -d strapi > backup.dump

还原 PostgreSQL 数据库:

# Standard restore
pg_restore --verbose --clean --no-acl --no-owner -h HOST -p PORT -U USERNAME -d "DATABASE_NAME" dump_file.dump

# Example for local database
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U postgres -d strapi backup.dump

将本地数据库上传到 Fly.io:

# 1. Export local database
pg_dump -Fc --no-acl --no-owner -h localhost -U postgres -d {dbname} > latest.dump

# 2. Proxy production database (run in separate terminal)
flyctl proxy 5433 -a {project-name}-db

# 3. In another terminal, restore to production
DB_USER={check_fly_dashboard}  # Get from Fly.io dashboard
DB_NAME={check_fly_dashboard}   # Get from Fly.io dashboard
pg_restore --verbose --clean --no-acl --no-owner -h localhost -p 5433 -U $DB_USER -d "$DB_NAME" latest.dump

# 4. Clean up
rm latest.dump

从 Fly.io 下载生产数据库:

# 1. Proxy production database (run in separate terminal)
flyctl proxy 5433 -a {project-name}-db

# 2. In another terminal, dump production database
DB_USER={check_fly_dashboard}
DB_NAME={check_fly_dashboard}
pg_dump -Fc --no-acl --no-owner -h localhost -p 5433 -U $DB_USER -d "$DB_NAME" > production.dump

# 3. Restore to local database
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U postgres -d {dbname} production.dump

# 4. Clean up
rm production.dump

用于直接访问的数据库代理:

# Proxy database to local port
flyctl proxy 5433 -a {project-name}-db

# Connect with psql
psql -h localhost -p 5433 -U {username} -d {dbname}

# Connect with GUI tools (PgAdmin, DBeaver, etc.)
# Host: localhost
# Port: 5433
# User: {from Fly.io dashboard}
# Database: {from Fly.io dashboard}
8. GitHub Actions CI/CD 集成

设置持续部署:

  1. 生成 Fly.io API 令牌:

    flyctl auth token
    
  2. 添加 GitHub 仓库机密:

    • FLY_API_TOKEN:你的 Fly.io API 令牌
    • ENV_PASS:环境加密密码(如果使用加密的 .env)
  3. 创建 .github/workflows/deploy.yml:

name: Deploy to Fly.io

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Fly.io CLI
        uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Decrypt environment variables
        run: |
          openssl enc -aes-256-cbc -pbkdf2 -salt -d \
            -in .env.enc.prod -out .env -k ${{ secrets.ENV_PASS }}

      - name: Deploy to Fly.io
        run: flyctl deploy --remote-only
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

CI/CD 最佳实践:

  • 使用 --remote-only 标志在 Fly.io 服务上构建
  • 分别设置预发布和生产工作流
  • 在部署后执行冒烟测试
  • 配置 Slack/Discord 部署状态通知
  • 使用 GitHub 环境为生产部署设置审批关卡
9. 监控与故障排除

基本监控命令:

# Check application status
flyctl status -a {project-name}

# View real-time logs
flyctl logs -a {project-name}

# View logs with filtering
flyctl logs -a {project-name} --region iad

# Check database status
flyctl status -a {project-name}-db

# View metrics
flyctl metrics -a {project-name}

# SSH into application
flyctl ssh console -a {project-name}

常见问题与解决方案:

  1. 端口配置问题:

    • 确认 fly.toml 中的 internal_port 与应用程序 PORT 匹配
    • 确保 HOST 设置为 "::",以兼容 IPv6
    • 检查 APP_URL 是否与部署的域名/URL 匹配
  2. 数据库连接失败:

    • 确认 DATABASE_URL 格式和凭据正确
    • 检查数据库是否与应用位于同一区域
    • 通过代理测试连接:flyctl proxy 5433 -a {project-name}-db
    • 查看数据库日志:flyctl logs -a {project-name}-db
  3. 环境变量问题:

    • 确认已设置机密:flyctl secrets list -a {project-name}
    • 加密前检查 .env 中的生产环境值
    • 解密时确保 ENV_PASS 正确
    • 更改后重新导入机密:flyctl secrets import
  4. 部署失败:

    • 查看构建日志:flyctl logs -a {project-name}
    • 检查 Dockerfile 或 buildpack 配置
    • 确认 package.json/requirements.txt 中包含所有依赖项
    • 部署前在本地测试构建
    • 如有需要,延长构建超时时间
  5. 应用程序崩溃:

    • 检查日志中的错误消息:flyctl logs -a {project-name}
    • 确认健康检查端点能够正常响应
    • 检查资源分配情况(内存、CPU)
    • 检查是否存在数据库连接问题
    • 通过 SSH 进入容器进行调试:flyctl ssh console -a {project-name}
10. 扩展与性能

垂直扩展(资源分配):

# Scale VM resources
flyctl scale vm shared-cpu-1x --memory 512 -a {project-name}

# Available VM sizes:
# shared-cpu-1x (256MB, 512MB, 1GB, 2GB)
# dedicated-cpu-1x (2GB, 4GB, 8GB)
# dedicated-cpu-2x (4GB, 8GB, 16GB)

水平扩展(机器数量):

# Scale number of machines
flyctl scale count 2 -a {project-name}

# Auto-scaling configuration in fly.toml:
[http_service]
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0  # Scale to zero when idle

区域部署:

# Add machines in multiple regions
flyctl regions add iad lhr syd -a {project-name}

# View current regions
flyctl regions list -a {project-name}

# Remove regions
flyctl regions remove lhr -a {project-name}
11. 成本优化

降低成本的策略:

  1. 自动停止/自动启动:在 fly.toml 中启用此功能,以便在空闲时段将规模缩减至零
  2. 合理配置资源:从最小 VM 规格开始,仅在需要时扩容
  3. 数据库优化:选择合适的 PostgreSQL 层级,并监控使用情况
  4. 区域策略:仅在有活跃用户的区域部署
  5. 监控:在 Fly.io 控制面板中设置账单提醒

成本监控:

# View current usage and costs
flyctl dashboard

# Check resource allocation
flyctl status -a {project-name}
flyctl status -a {project-name}-db

支持文件

此技能包含以下模板:

  • fly.toml.template:基本的 Fly.io 配置模板
  • deployment-checklist.md:部署前验证清单
  • github-actions-workflow.yml:CI/CD 工作流示例

通过以下路径访问:.claude/skills/flyio-deployment/templates/

常见部署模式

模式 1:首次生产部署
# 1. Setup and authenticate
flyctl auth login

# 2. Create database
flyctl postgres create  # Use {project-name}-db

# 3. Launch application
flyctl launch  # Don't deploy yet

# 4. Attach database
flyctl pg attach {project-name}-db -a {project-name}

# 5. Set secrets
flyctl secrets import -a {project-name} < .env

# 6. Deploy
flyctl deploy -a {project-name}

# 7. Verify
flyctl open -a {project-name}
flyctl logs -a {project-name}
模式 2:数据库迁移
# Export from source
pg_dump -Fc --no-acl --no-owner -h {source-host} -U {user} -d {db} > migration.dump

# Proxy Fly.io database
flyctl proxy 5433 -a {project-name}-db  # Separate terminal

# Import to Fly.io
pg_restore --verbose --clean --no-acl --no-owner \
  -h localhost -p 5433 -U {user} -d {db} migration.dump

# Verify
flyctl ssh console -a {project-name}
# Inside container: run database query to verify data
模式 3:回滚部署
# List recent releases
flyctl releases -a {project-name}

# Rollback to previous version
flyctl releases rollback -a {project-name}

# Or rollback to specific version
flyctl releases rollback {version-number} -a {project-name}

# Monitor rollback
flyctl logs -a {project-name}

安全最佳实践

  1. 环境加密:提交前务必加密 .env 文件
  2. 数据库访问:使用数据库代理,而不是公开暴露数据库
  3. API 令牌:将 Fly.io API 令牌存储在 GitHub 机密中,切勿写入代码
  4. SSL 证书:始终在 fly.toml 中启用 force_https
  5. 数据库备份:实施自动备份策略(S3、外部存储)
  6. 机密轮换:定期轮换 API 令牌、数据库密码和加密密钥
  7. 访问控制:使用 Fly.io 组织管理团队访问权限
  8. 网络安全:配置防火墙规则,限制数据库访问

验证清单

在确认部署完成前:

  • 应用可通过公共 URL 访问
  • 健康检查端点响应正常
  • 数据库连接正常
  • 所有环境变量均已正确设置
  • SSL 证书已签发且处于有效状态
  • 日志中没有错误
  • CI/CD 流水线已配置并经过测试
  • 已配置数据库备份
  • 已设置监控和告警
  • 文档已更新部署 URL 和操作步骤

实际使用中的注意事项(惨痛教训)

高风险账户锁定

Fly.io 会将长期未使用的账户标记为“高风险”。创建应用或数据库会失败,并显示:

您的账户已被标记为高风险。请访问 https://fly.io/high-risk-unlock

解决方法:必须在浏览器中登录 Fly 账户后访问该 URL。无法通过 CLI 绕过此限制。

自动停止非常激进

设置 auto_stop_machines = "stop" 和 min_machines_running = 0 后,机器会在空闲约 60 秒后停止。有些框架冷启动需要 5-10 秒。这意味着:

  • 空闲后收到的第一个请求响应较慢(唤醒 + 启动)
  • 快速连续发起的 API 调用之间,机器可能会停止
  • 批量操作前务必访问 /_health,并等待收到 204 响应
Fly 默认会创建 2 台机器

即使设置了 min_machines_running = 0,fly deploy 也会出于“高可用”目的创建 2 台机器。对于开发/预发布环境,请销毁第二台机器:

fly status --app <app>  # Find both machine IDs
fly machine stop <second-id> --app <app>
fly machine destroy <second-id> --app <app> --force
内部网络上 DATABASE_SSL 必须设为 False

fly postgres attach 会将 DATABASE_URL 设置为包含 sslmode=disable。如果应用设置了 DATABASE_SSL 环境变量,请将其设为 false:

[env]
  DATABASE_SSL = "false"
DNS + 证书设置(Cloudflare)

使用 Cloudflare 管理 DNS 时:

  1. 记录必须关闭代理(proxied=false)——Fly 需要直接流量来终止 TLS
  2. 检查过期记录——旧部署可能遗留了开启代理的 A/AAAA 记录。请先删除这些记录。
  3. ACME CNAME——fly certs setup 会提供 _acme-challenge CNAME 目标。请创建或更新该记录,以通过 Let's Encrypt 验证。
  4. DNS 设置正确后,证书通常会很快签发(约 30 秒)。
部署标志:没有 --region

请使用 --primary-region,或在 fly.toml 中设置 primary_region。fly deploy 不支持 --region 标志。

Bash 令牌管道错误

较长的 API 令牌(256 个字符或更多)通过 Bash 变量展开并传给 curl 时,会导致标准输出为空。可采用以下替代方法:

  • 将令牌存入文件:echo -n "TOKEN" > /tmp/.token && TK=$(cat /tmp/.token)
  • 使用 curl 的 -o file 参数,而非通过管道传输
  • 使用 Python urllib.request(在沙盒环境中最可靠)

其他资源

注意事项

  • 正式环境部署前,务必在预发布环境中测试部署
  • 保持 flyctl CLI 更新:flyctl version update
  • 关注 Fly.io 状态页面,了解平台故障
  • 加入 Fly.io 社区,获取支持并了解最佳实践
  • 对于生产工作负载,可考虑使用 Fly.io 托管的 PostgreSQL

评论

支持 Markdown