Transferring files to and from a Fly.io volume

how to manage data on a persistent volume

  •  2 mins  •  

Fly.io provides a generous free tier, including up to 3 VMs with shared CPUs and up to 256MB of RAM. That's more than enough to run 3 simple web apps.

I've run many things on Fly.io, including the Ghost blogging platform, Telegram bots, and miscellaneous backend services.

One thing to note when before migrating to Fly.io is that since it's marketed towards developers, most of the functionality is primarily available via the flyctl CLI tool. But the tool is fairly simple to use, so this shouldn't be much of a problem.

A more significant annoyance for me was that Fly.io doesn't provide a straightforward way to access and modify the persistent volumes that are attached to VMs. For instance, I might want to copy the contents of a volume to my local environment to test on 'production' data, or I might want to import data when migrating an app to Fly.io. I did not see any simple and fuss-free way to accomplish this.

My solution is to SSH into the VM and then transfer the data using rsync or similar.

Getting SSH access

It is not possible to SSH into a VM from an external IP address by default, so you should first proxy your connection:

flyctl proxy 10022:22

This proxies port 22 on the VM to port 10022 locally. I've used 10022 as an arbitrary port. You can proxy to any unused port (just remember to specify that port when you SSH in later).

Next, get a SSH private key:

flyctl ssh issue

I stored mine in ~/.ssh/fly_temp. It will be valid for 24 hours only, but you can repeat the process if you need it again.

If you just want to SSH in, you can run flyctl ssh console instead.

SSH in

At this point, you can already SSH in:

ssh -p 10022 -i ~/.ssh/fly_temp root@localhost

The username you should use will vary depending on what Docker image you have deployed. I'm using an Alpine image, hence it's root. It might be ubuntu for Ubuntu images, etc.

However, rather than run ad-hoc SSH commands with a bunch of flags and arguments, I found it more convenient to edit my SSH config at ~/.ssh/config:

Host fly
  HostName localhost
  Username root
  IdentityFile ~/.ssh/fly_temp
  Port 10022

This also allows you to rsync your files easily:

rsync -aP ~/files/ fly:/app/files/