your config looks right as @Reiner_Nippes stated before.
as the easiest proof I suggest following procedure:
upload the through Nextcloud (browser, client, WebDAV)
check the file system of your docker host ./app/data (where your docker-compose file lives)
new file should exists at ./app/data > [your user id] > [Nextcloud relative path to the file]
you could perform additional checks like rename and remove the file with Nextcloud client and monitor file system changes on docker host system.
Until you use encryption all Nextcloud files are are visible and accessible in [data root]/[user id] Meta-data like comments and shares are stored in the database should be checked/verified there…
A persistent volume in Docker is one that’s named in the configuration, either a named Docker volume or a mount path on the host (the latter being what you have in your config). You can look (but don’t touch) in these folders on your host and see that the data is there. These folders will have that data in them even if you completely deleted your containers.
everthing you use in the -v aka volumes: section is persistent on your host.
the difference is: if you use path name starting with / or ./ docker uses this path on the host. (aka bind mount)
if you use “only” a name like nextcloud docker will use a path below /var/lib/docker/... (aka named volume).
so the answer to your question: don’t put a / or ./ in the “name” of the volume.