The volumes live on Fly.io servers, so it has nothing to do with your local machine.
You have to use the CLI to provision a volume with a name. In this case that name is app_data. When the machine spins up, it attaches a volume from a pool of volumes with the names app_data.
The destination, is the location on the VM where that volume will be mounted too.
I use docker compose locally, and I attach volumes on my local machine all the time to validate functionality before deploying. But it has nothing to do with Fly volumes.
That being said, I don’t have the VOLUME baked into the docker image, as much as docker compose inserts it. So when fly reads the docker image, and builds the VM (not a docker container), the VOLUME ins’t listed at all.
Instead I would use COPY or ADD to add the files from the source file system you want to preserve and send to Fly.
ADD /app/data /app/data
The reason for the volume is because your running it locally and want to preserve data changes that happen in the docker image. For example you have a data.sqlite database you want to persist between container restarts.
For fly, the volume created with the CLI, and attached via the [mounts] sections handles that.
For local development, the Docker volume can handle that.
I have not seen that fly uses the VOLUME command but have not tried it.