I have one file in this /data directory, data.json. data/data.json is listed in my .dockerignore file, but when I run flyctl deploy, the app can’t find the data.json file. Is there a way to have the data.json file preserved between deploys?
The way I understand what you’re saying is: you’re expecting your local data/ directory to be mounted in your instance?
If that’s what you are expecting, then the reality is a bit different: volumes are empty and they’re generally populated by your app at runtime. They persist across reboots, but their source is independent of a deployment.
You can upload a file in there to “bootstrap” your volume if fly sftp shell (I think there’s a way!) or uploading it somewhere else and then downloading it from a shell (acquired by fly ssh console).
Is there actually a file in /data/data.json in the volume? (Sounds like no!)
If that file is added in via your Dockerfile, then it won’t end up in your volume.
When a VM is spun up with a volume, the volume is mounted to the directory of your choosing (/data in your case) and any contents in /data are “overwritten” (hidden, technically).
So, to get files into your volume, you need to add data after the VM is running (via entrypoint script, or some other boot process, or by SSH-ing into the instance and adding the file yourself manually).
Usually there is a file in /data/data.json. To clarify, I have a local copy of the /data/data.json file, and before now I have been adding it via my Dockerfile. Originally I was expecting the volume to work as jerome described it, but I’m now trying to add the file in after the VM starts running.
I’ve tried uploading the file using flyctl sftp shell, and I’ve used flyctl ssh console to verify that the file exists and is in the right directory. However, if I try to run flyctl deploy again, regardless of whether the local copy is in my .dockerignore, the file no longer persists.
Am I understanding the process correctly, or am I missing a step?
That sounds like it may not be writing to the volume properly. Will you try running fly ssh console -C "df -h"? This will show you where the different devices are mounted. You want something like this:
➜ ~ fly ssh console -a fizz-db -C "df -h"
Update available 0.0.442 -> v0.0.444.
Run "fly version update" to upgrade.
Connecting to fdaa:0:446b:a7b:1f61:0:784f:2... complete
Filesystem Size Used Avail Use% Mounted on
devtmpfs 485M 0 485M 0% /dev
/dev/vdb 7.9G 971M 6.5G 13% /
shm 489M 76K 488M 1% /dev/shm
tmpfs 489M 0 489M 0% /sys/fs/cgroup
/dev/vdc 9.8G 239M 9.1G 3% /data
If your RUN or ENTRYPOINT try to create a /data/ directory, it could be overwriting the mount location. You can also try mounting the volume at like /data2/ to see if you get different behavior.
@fideloper-fly thanks for this info! Would be great to get this also in the docs - I was looking specifically for this, and was unable to find the detail of “when is a volume available - before or after Dockerfile”
I was also considering a feature request: a new copy_initial_data_from_destination setting under [mounts] in fly.toml (default: false)
…but upon more thought, I think it would be challenging to get right, because the data from the Dockerfile could change at any time, eg. when there are conflicting files already existing in the volume in future. So then it gets into syncing territory, which makes it challenging to work with.