All skills
wshaddix avatar

/fly-io

@0d51225

Deploy, configure, and manage applications on the Fly.io platform using flyctl CLI, fly.toml configuration, Fly Machines, Fly Volumes, private networking, secrets, health checks, autoscaling, and GitHub Actions CI/CD. Use when deploying any application to Fly.io, writing or modifying fly.toml configuration, managing Fly Machines or Volumes, configuring networking (public services, private 6PN, Flycast, custom domains, TLS), setting secrets, configuring health checks, setting up autostop/autostart or metrics-based autoscaling, deploying with GitHub Actions, managing Fly Postgres databases, or preparing an app for production on Fly.io.

Use this Skill: https://skilld.dev/gh/wshaddix/dotnet-skills/fly-io

This session only. Nothing lands on disk.

referencescicd-github-actions.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Fly.io CI/CD with GitHub Actions

Table of Contents

Basic Deployment Workflow

Setup Steps

  1. Generate a deploy token: fly tokens create deploy -x 999999h
  2. Add FLY_API_TOKEN repository secret in GitHub Settings -> Secrets and variables -> Actions
  3. Create workflow file:
# .github/workflows/fly.yml
name: Fly Deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    name: Deploy app
    runs-on: ubuntu-latest
    concurrency: deploy-group
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Ensure fly.toml is committed to the repository (do not .gitignore it when using GitHub Actions).

With Environment Secrets

deploy:
  name: Deploy app
  runs-on: ubuntu-latest
  environment: production
  steps:
    - uses: actions/checkout@v4
    - uses: superfly/flyctl-actions/setup-flyctl@master
    - run: flyctl deploy --remote-only
      env:
        FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Deploy Tokens

App-specific deploy token (recommended for CI):

fly tokens create deploy -x 999999h     # Long-lived deploy token for one app

Copy the entire output including FlyV1 prefix and space.

Org-wide auth token (manages all apps):

fly auth token                           # Full-access token

Use app-specific deploy tokens in CI for least-privilege access.

Review Apps (PR Previews)

Deploy ephemeral preview apps for each pull request:

# .github/workflows/fly-review.yml
name: Fly Review App
on:
  pull_request:
    types: [opened, reopened, synchronize, closed]

env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

jobs:
  review:
    runs-on: ubuntu-latest
    concurrency:
      group: pr-${{ github.event.number }}
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master

      - name: Deploy review app
        if: github.event.action != 'closed'
        run: |
          APP_NAME="pr-${{ github.event.number }}-my-app"
          flyctl apps create $APP_NAME --org my-org || true
          flyctl deploy --remote-only --app $APP_NAME --config fly.review.toml
          echo "Deployed to https://$APP_NAME.fly.dev" >> $GITHUB_STEP_SUMMARY

      - name: Destroy review app
        if: github.event.action == 'closed'
        run: |
          APP_NAME="pr-${{ github.event.number }}-my-app"
          flyctl apps destroy $APP_NAME --yes || true

Create a fly.review.toml with smaller Machine sizes and fewer instances for cost efficiency.

Multi-App / Monorepo Deploys

Deploy multiple apps from one repo using path filters:

name: Deploy Services
on:
  push:
    branches: [main]

jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      api: ${{ steps.filter.outputs.api }}
      web: ${{ steps.filter.outputs.web }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v2
        id: filter
        with:
          filters: |
            api:
              - 'services/api/**'
            web:
              - 'services/web/**'

  deploy-api:
    needs: detect-changes
    if: needs.detect-changes.outputs.api == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only --config services/api/fly.toml
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

  deploy-web:
    needs: detect-changes
    if: needs.detect-changes.outputs.web == 'true'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only --config services/web/fly.toml
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Deployment Strategies in CI

Rolling Deploy (Default)

No extra config needed. Machines replaced one-by-one.

Canary Deploy

# fly.toml
[deploy]
  strategy = "canary"

One new Machine deployed first. If health checks pass, remaining Machines are updated via rolling. If the canary fails, deploy halts. Cannot be used with volumes.

Blue-Green Deploy

# fly.toml
[deploy]
  strategy = "bluegreen"

New Machines boot alongside existing ones. Traffic migrates after all health checks pass. Requires health checks to be configured. Cannot be used with volumes.

Staging Before Production

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only --app my-app-staging
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN_STAGING }}

  smoke-test:
    needs: deploy-staging
    runs-on: ubuntu-latest
    steps:
      - run: curl -f https://my-app-staging.fly.dev/health

  deploy-production:
    needs: smoke-test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only --app my-app
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN_PROD }}

Database Migrations in CI

Use the release_command in fly.toml to run migrations before deployment:

[deploy]
  release_command = "bin/rails db:migrate"
  release_command_timeout = "10m"

The release command runs in a temporary Machine with your app's image. It does NOT have access to volumes. Non-zero exit code aborts the deploy.

Source: SKILL.md on GitHub

1 alert14d3 checks · Risk HIGH
  • Gen Agent Trust Hub14d

    The skill provides comprehensive guidance for deploying and managing applications on the Fly.io platform. It includes installation instructions for official tooling and defines common workflows for infrastructure management. A minor vulnerability surface exists regarding the processing of user-provided configuration files.

  • Socket14d

    No alerts

  • Snyk14d

    Risk: LOW · No issues

Signed by skilld at 0d51225. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for wshaddix/dotnet-skills/fly-io