Deployment
Fly CI/CD
Automated deployments with GitHub Actions
When to use this page
- You want automatic Fly deployments from GitHub.
- You need repeatable staging/production deploy workflows.
Prerequisites
- Fly app already deploys manually with
fly deploy. - GitHub repository with Actions enabled.
FLY_API_TOKENavailable from Fly CLI.
Manual deploys are useful when you need explicit release control. For staging and fast iteration, GitHub Actions usually provides a better default.
Documentation: https://fly.io/docs/launch/continuous-deployment-with-github-actions/
Step 1: Create deploy token
Generate a long-lived deploy token using the Fly CLI:
fly tokens create deploy -x 999999hStep 2: Add token to GitHub
Add the generated token as a repository secret in your GitHub repository:
- Go to Settings → Secrets and variables → Actions
- Create a new secret named
FLY_API_TOKEN - Paste the token value
Step 3: Create GitHub Actions workflow
Create a workflow file (e.g. .github/workflows/deploy-production-api.yml):
name: Production - Deploy API
on:
push:
branches:
- main
- deploy-production-api/**
paths:
- apps/api/**
- packages/email-templates/**
- .github/workflows/deploy-production-api.yml
- fly.toml
jobs:
deploy_api:
runs-on: ubuntu-latest
environment:
name: production
defaults:
run:
working-directory: ./
concurrency: deploy-production-api
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only --dockerfile ./apps/api/Dockerfile
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}Key configuration options
- branches — trigger deploys on pushes to specific branches. Use patterns like
deploy-production-api/**to allow manual trigger branches - paths — only trigger when relevant files change (e.g. your app code, shared packages, the workflow file itself, or
fly.toml) - environment — use GitHub environments to require approvals for production deploys
- concurrency — prevents multiple deploys from running simultaneously
--remote-only— builds the Docker image on Fly's remote builders instead of locally--dockerfile— specify the Dockerfile path for monorepo setups
Verify
- A push to configured branches triggers the workflow.
- Workflow finishes with successful deploy status.
- Fly app revision changes and health checks pass.
Troubleshooting
- GitHub action fails authentication:
Confirm
FLY_API_TOKENexists and belongs to the correct Fly organization. - Deploy triggered too often: Tighten branch/path filters in the workflow.
- Parallel deploy conflicts:
Ensure
concurrencykey is present and scoped correctly.