Deploy a Fly App

All new apps on the Fly Platform are V2 Apps, running on Fly Machines. Our docs apply to V2 Apps, but we still include legacy V1 Apps info where appropriate.

We’re migrating all V1 Apps to V2 in phases. Learn more about how and why we’re getting off Nomad.

You can also migrate your V1 app yourself using our migration and migration troubleshooting tools, or migrate your V1 app manually.

The fly deploy flyctl command builds your Fly App and spins it up on one or more Fly Machines, applying the configuration specified in a local fly.toml file.

Whether you’ve run fly launch but haven’t deployed yet, or want to apply changes to your deployed Fly App’s source or configuration, you can make a new release by running

fly deploy

from the source directory of your project, where any app source code, project config, fly.toml, and Dockerfile are located.

If you haven’t deployed the app before, fly deploy creates one or two Machines for every process group defined in the app’s fly.toml file, depending on whether there are services and volumes configured. If you haven’t explicitly defined any process groups, the first deployment gives you two Machines for redundancy. For more information about when Fly Launch creates one Machine or two Machines, refer to Redundancy by default on first deploy.

Subsequent deployments update the app’s Machines as a group, with the latest local changes to the app’s source and configuration. It’s possible for a Fly App to have standalone Machines that aren’t managed by fly deploy.

Configuration

flyctl will look for a fly.toml file to find the name of the app to operate on, and for an app configuration to apply during deployment. Use fly deploy -a <app-name> to override the app name given in fly.toml and deploy the project in the current working directory to a different existing Fly App.

There are a number of other options you can use with the fly deploy command.

The build

fly deploy builds, or gets, the Docker image for the app, and refreshes Machines with the latest changes.

Here’s how fly deploy determines how to get the app’s Docker image:

  1. If an image is specified, either with the --image option or in the [build] section of fly.toml, use that image, regardless of the presence of a Dockerfile in the working directory or the use of the --dockerfile option.
  2. Otherwise, check the [build] section of fly.toml and use the method specified there, whether it’s a Dockerfile or a buildpack (but don’t use buildpacks if you don’t have to; they’re brittle, bloated, and prone to change).
  3. Otherwise, if the --dockerfile flag supplies a path to a Dockerfile, use that Dockerfile to build the image. You read that right. The --dockerfile flag is looked at after the [build] section of the config file. This will hopefully change soon.
  4. Otherwise, if there’s a Dockerfile (named exactly Dockerfile or dockerfile) in the local working directory, use that Dockerfile for the build.

IP addresses

If the app to be deployed is configured with an eligible HTTP [[services]] section, and it does not yet have public IP addresses, fly deploy provisions a public IPv6 and a shared public IPv4 Anycast address.

Machines not managed by Fly Launch

Machines created using fly deploy (or as part of a deployment during fly launch), or by fly cloneing such a Machine, carry a piece of metadata marking them as belonging to Fly Launch. These machines are updated as a group on all subsequent fly deploy commands, as are Machines that existed on a Machines App at the moment that it was migrated to a V2 App.

New Machines created within a V2 App using fly machine run don’t have the V2 Apps metadata, and are not automatically managed by Fly Launch (fly deploy), so these Machines can have their own configuration different from that of the App, and can even be based on a different Docker image.

Volume mounts and fly deploy

If a Machine has a mounted volume, fly deploy can’t be used to mount a different one. You can change the mount point at which the volume’s data is available in the Machine’s file system, though. This is configured in the [mounts] section of fly.toml.

Learn more about using Fly Volumes with Fly Apps.

fly deploy configuration in fly.toml

Configure the following deployment behavior in the [deploy] section of fly.toml.

Release commands

You can run a one-off release command in a temporary VM—using the successfully built release—before that release is deployed. This is good for, e.g., running database migrations.

Deployment strategy

You can specify one of the following deployment strategies:

  • rolling (default): wait for each Machine to be successfully deployed before starting the update of the next one
  • immediate: bring all Machines down for update at once
  • canary: boot a single new Machine, verify its health, and then proceed with a rolling restart strategy
  • bluegreen: boot a new Machine alongside each running Machine in the same region, and migrate traffic to the new Machines only once all the new Machines pass health checks

Learn more about setting a deployment strategy.

fly deploy --strategy canary
...
==> Building image
Searching for image 'flyio/hellofly:latest' remotely...
image found: img_z1nr0lpjz9v5q98w

Watch your app at https://fly.io/apps/aged-water-8803/monitoring

Creating canary machine for group app
  Machine 328745da023e85 [app] update finished: success
Canary machines successfully created and healthy, destroying before continuing
machine 328745da023e85 was found and is currently in created state, attempting to destroy...
Updating existing machines in 'example-app-8803' with canary strategy
  [1/2] Machine 3287457df77785 [app] update finished: success
  [2/2] Machine 91857266c41638 [app] update finished: success
  Finished deploying
...

Not all changes require a new App release

You can add an IP address to an App, for example, without redeploying.

Adding a secret to the App does require a restart, so fly secrets set triggers a new deployment.