SFTP direct access to Volumes

Does anyone know if there is a way to access a volume directly(to transfer files to it)? I saw this thread, but that seems to rely on there already being a VM active to SSH into.

3 Likes

As in, spin up volumes but not attach it to a VM and then be able to S/FTP to it…?

The closest one can get to such a setup is with volumes attached to on-demand VMs (viz. Apps v2 / Fly Machines). These Machines / VMs only spin up when there’s a request to be served (fly ssh console, for example) and then it is left up to the Machine’s / VM’s entrypoint process to determine when it must quit (docs).

Ok, that’s not insurmountable, but it is pretty annoying. My app is a standard VM that requires the files to be available to it to start. I can deploy a temporary version of it that allows me to bootstrap it, but it is just a tad irritating that I’m not able to generate them locally and them transfer them directly(without any extra VMs).

How big is your docker image, currently? If the files aren’t anything too huge (think 4GB or less) you can consider bundling them up in the docker image itself; ref: Read-only database: Docker vs Volume - #2 by ignoramous

Otherwise, you’ll need to download the files from elsewhere, like S3 or some such.

The files are config-related, so I was hoping that I would be able to not have to bundle them directly into the image(and to be honest, I’m not 100% sure that they are read-only), but that is an idea.

1 Like

On the other side, you get config-as-code if you do bundle it with the docker image…

Gotcha. You could opt to store in an external store like DynamoDB or Workers KV. Fly does have a KV store in Fly-managed Uptash Redis, and your usecase may be covered by its free tier. Lastly, it isn’t a KV store, but another Fly-specific alternative would be deploy (and maintain) LifeFS (docs).

Experimental Consul support is also available to Fly apps that one may (ab)use to store configs… (though I haven’t see any one recommend it on here).

I am running into this issue. I have a volume I am creating with the intention of uploading assets to. My app won’t start without those assets, however.

Chicken and egg issue. If I need the assets to run my app, but I need the app to be running to scp the assets to the volume.

What do I do?

If your files are small, like config files you don’t want to build into the image, I’d suggest looking into sending them along with the Machine config:

(Docs)

(Edit: I suspect the above doesn’t work to deposit the files on a persistent volume, but I haven’t asked or tried it)

Otherwise, there are a few ways to get a generic Machine running long enough to transfer files up, then either update that Machine or destroy it and attach a new one to the volume. One possible route is to add this to your fly.toml for your first deployment, to override the CMD in your Docker image:

[experimental]
 cmd = ["sleep", "inf"]

(Docs)

Once the Machine boots up, do your file transfer with fly sftp or whatever, then remove that section from fly.toml and redeploy.

If you’re planning multiple instances, look into fly volume fork to copy the volume to your desired region once you’ve populated it, before scaling up with fly machine clone using the --attach-volume flag.

Another way that’s convenient, when practical, is to write an entrypoint script that checks for the assets on the volume and retrieves them from somewhere if they’re absent, before carrying on with starting up your app process. That would, I think, let you scale out using fly scale count.

Hope something in there is useful!

1 Like

For the record, I did give this a go. I was unable to get it to work. I may have to alter my code to allow the database files to be opened after they are copied over.

The error I kept getting was:

Error: Process group ‘app’ needs volumes with name ‘databases’ to fullfill mounts defined in fly.toml; Run fly volume create databases -r REGION -n COUNT for the following regions and counts: sjc=1

I did have the volume created and all.

Another way that’s convenient, when practical, is to write an entrypoint script that checks for the assets on the volume and retrieves them from somewhere if they’re absent, before carrying on with starting up your app process. That would, I think, let you scale out using fly scale count.

I tried exploring this method, too. When I deploy an app, fly checks that the http_service is running. If the entry point script is still trying to download a file from the blob store and doesn’t respond to HTTP requests, Fly tries to restart the entire process. Which flubs the whole thing.