Migrate an Existing Fly App to Apps V2
A V1 (Nomad) App
Update: We have an automated tool you can run to migrate an existing V1 app to Apps V2.
If you'd rather work through the process manually, here are some steps to convert a fairly simple existing "V1" (managed by Nomad) Fly App to Apps V2 (running on Fly Machines).
The idea is to get the new app up and running satisfactorily, keeping your old one running until you're comfortable to migrate DNS to the new Machines-based app.
Create a New App With the V2 (Machines) Platform
fly apps create --machines --name <my-app-v2> -o <my-org>
Put the New App Name Into the fly.toml
Config File
Edit fly.toml
in place, or make a duplicate of your app's source directory to use for the new app.
Replace the app name with the new app name. If your new app is literally called my-app-v2
, that line looks like this:
app = "my-app-v2"
Set the App's Primary Region
Still in fly.toml
, add a primary_region
option, which fly deploy
in Apps V2 uses to determine where to create new Machines, as well as to set the PRIMARY_REGION
environment variable within the Machines it deploys. Replace ord
with the three-letter code for your Fly Region of choice.
primary_region = "ord"
Note: Apps V2 does not make use of region groups or fly regions
commands. Use fly machine clone --region
to create Machines in specific regions.
Copy Any Secrets You Need From Your Existing App
Find out which secrets you need to recreate with
fly secrets list -a <my-old-app>
A quick way to see those secrets is
fly ssh console -C env -a <my-old-app>
Set secrets on the new app to match with fly secrets set
. For example:
fly secrets set DATABASE_URL=<database-url-from-old-app> REDIS_URL=<redis-url-from-old-app>
in the new app's working directory.
Here's a shell script to combine the above steps, using the ability of fly secrets import
to import key=value pairs from stdin:
#!/bin/sh
#
# Clone secrets from one Fly app to another
TEMPFILE=`mktemp`
trap "rm -rf $TEMPFILE" EXIT
SECRET_KEYS=`fly secrets list -a $1 | tail -n +2 | cut -f1 -d" "`
fly ssh console -a $1 -C env | tr -d '\r' > $TEMPFILE
for key in $SECRET_KEYS; do
PATTERN="${PATTERN}\|${key}"
done
grep $PATTERN $TEMPFILE | fly secrets import -a $2
A Note on Fly Volumes
If your app uses Fly Volumes, you'll have to provision a volume for the first Machine to be deployed. Volumes cannot be transferred between apps, you may need to copy data down from the old app, or create the new volume from a snapshot.
Horizontal scaling of Machines is done using fly m clone
, which will provision a new volume for the new Machine but will not copy any data into it; it's up to your app to do data replication between instances, if needed.
Deploy Your New V2 App
fly deploy
(If the app has HTTP/HTTPS services configured on standard ports, the first deployment will provision a dedicated public IPv6 and a shared public IPv4 address for it.)
Check that your app is running correctly. You can see information about your deployment in
fly status
More ways to get info about an app, its Machines, and its status
Make Sure the Machines' Restart Policy Suits Your App
Fly Machines have a restart policy as part of their configuration, determining whether the Machine should restart when its main process exits, or just enter the stopped
state.
There are three possible policies: no
, always
, and on-fail
.
The default policy configured by fly deploy
is equivalent to on-fail
: flyd will try restarting a Machine up to 10 times if it exits with a non-zero exit code.
There is a temporary gotcha with this policy, however: right now, when a host reboots, this is not recognised as a failure, and so Machines enter the stopped
state when the host comes up, instead of being restarted. Machines with services configured will tend to be woken by Fly Proxy in the course of its load-balancing activities, but Machines without services will stay stopped until you start them.
We recommend updating such Machines to use the always
restart policy, to ensure that they come back up after a host reboot:
fly machine update --restart always <machine-id>
See more about restart policies here.
Scale Your Deployed Machine(s)
First deployment spins up a Machine with a single shared CPU core and 256MB RAM. If your app needs more oomph, scale it with fly m update
.
Scale Out
For a production app, you should have at least two VMs provisioned for each process. Unlike Nomad, flyd does not attempt to move VMs if their host hardware fails. Having VMs in multiple regions improves availability in the case of regional outages. Databases likely want redundancy within a region for failover purposes.
To scale your app horizontally, you can clone an existing VM:
fly m clone --select
If you need to deploy in another region, also clone, but into another region:
fly m clone --select --region ams
Add and Check Certs; Switch DNS
If you have domains/certs attached to your app, you'll want to add them here again:
fly certs add <my-custom-domain.com>
The output will show you the IP allocated for your app, or you can use fly ips list
.
Check that any certificates have been issued:
fly certs check
dig txt _acme-challenge.mydomain.com +short
Finally, point your DNS to the new IP allocated for your app.
Delete the Old V1 App
Once you've switched over to the new V2 app and you're confident you don't need the V1 app anymore, delete it.
A Non-platform Machines App
The Fly Apps V2 platform allows you to manage Fly Machines with app-wide configuration and coordinated releases, using fly launch
and fly deploy
. If you have a non-Apps-V2 Machine app—created using fly create --machines
or fly machine run
—you may or may not want to migrate it onto the Apps V2 platform in order to gain fly deploy
functionality.
fly deploy
unifies all the Machines it manages to use a single Docker image and a single configuration. As an example, the services and environment variables will come from fly.toml
on the next deployment, replacing whatever was present before.Thus, migrating a Machines Fly App to the Apps V2 platform is fairly straightforward if all the Machines belonging to the app are running the same image with the same configuration.
From your project's root directory (where you'll be deploying it from, and where fly.toml
should live):
$ fly config save -a appname # to get a fly.toml from a machine's config
$ fly machine update --metadata fly_platform_version=v2 9080eee5a1d518 # do this for each machine
$ fly deploy
For an app with Machines running different images, it's more awkward. There's a good chance you'd be better off starting with a fresh V2 app, and adding any special Machines with fly machine run
after it's deployed.
fly config save
doesn't expect there to be a difference between Machines, so it's not currently possible to select a specific Machine to pull a new app config from. In this case, the process would look more like:
- get or create a
fly.toml
to match the config you wantfly deploy
to apply to its Machines - run
fly machine update --metadata fly_platform_version=v2 <machine-id>
only on any Machines that you wantfly deploy
to manage. fly deploy
This deployment now updates the adopted Machines with the app-wide image and configuration.