The difference between the named volumes and bind mounts is as follows (I hope I understand this correctly based on what I read in the docs).
When you use named volume
- n8n_storage:/home/node/.n8n
Docker creates this volume automatically if it doesn’t exist, and (what is importnat) initializes it with the contents of the target directory in the image (i.e. the contents of /home/node/.n8n inside the container). This means that the the app files that n8n expects are preserved, nothing is overwritten [1].
On the other hand, with the bind mount
- ./n8n_data:/home/node/.n8n
Docker does not copy anything into this directory - it simply overrides the container’s /home/node/.n8n folder with whatever is in your local folder, which causes node_module and all the good stuff to be missing, including the start script in package.json, and I assume this is what happens in your case [2].
The easiest way to go about this is:
- use named volume
- if you need to access to files in the volume, this is what you can do:
- run
docker inspect n8n_n8n_storage(wheren8n_n8n_storageis the name of your named volume) - find the
MountPointfield, this is where you can access the volume on the host machine.
$ docker volume list | grep n8n_storage
local n8n_n8n_storage
$ docker inspect n8n_n8n_storage | grep Mount
"Mountpoint": "/var/lib/docker/volumes/n8n_n8n_storage/_data",
$ sudo ls /var/lib/docker/volumes/n8n_n8n_storage/_data
binaryData config crash.journal custom git nodes ssh
Hope it helps.