Authentication for automation
FLY_API_TOKEN
Set theFLY_API_TOKEN environment variable to authenticate flyctl without interactive login:
fly auth login. flyctl also honors FLY_ACCESS_TOKEN as an alternative name for the same value. If both variables are set, FLY_ACCESS_TOKEN takes precedence.
If you’re testing a token env var locally on a machine where you’re also logged in to flyctl, run fly auth logout first. This command revokes and removes the token saved by fly auth login; it doesn’t revoke or unset tokens supplied through environment variables. The env var wins for each command, but mixing it with a saved login can cause confusing behavior: fly auth whoami shows a token identity rather than your user, and scope-limited tokens silently filter output from commands like fly apps list instead of erroring. In CI, this isn’t an issue because there’s no saved login.
Token types
Use the narrowest scope that works for your use case. Deploy token (single app) This is the default choice for CI deploys:-x flag sets expiry; 720h is 30 days. Without -x, tokens default to 20 years.
Org deploy token For multi-app pipelines or org-wide automation:
--command is -C (uppercase).
Read-only org token For automation that only needs to read state:
fly tokens create org) but can’t create, deploy, or modify anything. Good for monitoring scripts, status dashboards, or any workflow that only consumes data from the Fly API.
Token management
List active tokens:fly tokens list):
--access-token, FLY_ACCESS_TOKEN, or FLY_API_TOKEN without looking up its ID:
FLY_ACCESS_TOKEN token first, unset FLY_ACCESS_TOKEN, and run the command again to revoke the FLY_API_TOKEN token.
Least-privilege guidance
- Use deploy tokens for CI. They can’t access other apps or org-level resources.
- Use read-only tokens (
fly tokens create readonly) for any automation that only needs to read state, such as monitoring, status checks, reporting. They can’t deploy or modify resources, so they’re safe to distribute more widely than deploy tokens. - Set expiry times. Short-lived tokens (
-x 24h,-x 720h) limit the blast radius of a leaked secret. - Rotate tokens on a schedule. Revoke old ones; create new ones.
- Never use
fly auth tokenin CI, because it returns your full personal token with access to everything. This command is deprecated and hidden from flyctl’s help output; usefly tokens createinstead.
FLY_APP
SetFLY_APP to specify the target app without passing -a on every command:
GitHub Actions
For a full walkthrough of setting up continuous deployment, see Continuous deployment with GitHub Actions. The basics: use thesuperfly/flyctl-actions/setup-flyctl action to install flyctl, store your token as a repository secret, and run commands.
Standard deploy workflow
Monorepo: deploy multiple apps
Use a matrix strategy to deploy several apps from one repository. Each app directory needs its ownfly.toml.
Staging-to-production promotion
Deploy to staging on every push. Deploy to production when you create a release.Running arbitrary flyctl commands
You aren’t limited tofly deploy. Any flyctl command works in Actions:
JSON output for scripting
Many flyctl commands support--json (or -j) for machine-readable output. Some commands return a single JSON object; others stream JSON-NL (one JSON object per line).
Examples
Get machine IDs and states:-e flag makes jq exit with a non-zero status if the expression evaluates to false or null, which works well in CI checks.
Remote builds
By default,fly deploy builds your image remotely on Fly.io infrastructure. You don’t need Docker installed locally.
Build modes
Remote build (default):--buildkit, try again without the flag before digging into the failure. The classic remote builder is the supported path for now.
Local build:
Notes on caching
- The first build on a new builder has no cache and takes longer.
- Subsequent builds reuse Docker layers. Structure your Dockerfile to maximize cache hits (dependencies before source code).
-
If you consistently see slow builds, check the order of your Dockerfile. Copy dependency manifests, install them, then copy the rest of your source:
If the install runs after you copy the full source, any source change invalidates the install layer’s cache and forces a reinstall on every build, negating the benefit.
- Uncompressed images on standard Machines are limited to 8 GB, matching the maximum rootfs size. Larger images can’t be deployed, so you’ll need to reduce the image size.
Other CI systems
The same patterns work in any CI system. The setup is always:- Install flyctl.
- Set
FLY_API_TOKEN. - Run flyctl commands.
Install flyctl in CI
Generic CI example
FLY_API_TOKEN, and run flyctl commands as you would locally.