Question: Docker Swarm can manage two types of storage:

`volume` and `bind`

While `bind` is not suggested by Docker Documentation since it creates a binding between a local directory (on each swarm Node) to a task, the `volume` implementation is not mentioned, so I don't understand how volumes are shared between tasks?

* How does Docker Swarm shares volumes between nodes?
* Where are volumes saved (on a manager? And if there is more than one manager?)
* Is there no problem between nodes if it's running on different machines on different networks?
* Does it create a VPN?

Answer: 
My solution for AWS EFS, that works:

1. [Create EFS](https://docs.aws.amazon.com/efs/latest/ug/gs-step-two-create-efs-resources.html) (don't forget to open NFS port 2049 at security group)
2. Install nfs-common package:

`sudo apt-get install -y nfs-common`
3. Check if your efs works:

```
mkdir efs-test-point
sudo chmod go+rw efs-test-point
```

```
sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport [YOUR_EFS_DNS]:/ efs-test-point
```

```
touch efs-test-point/1.txt
sudo umount efs-test-point/
ls -la efs-test-point/
```

> 
> directory must be empty
> 
> 
> 

```
sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport [YOUR_EFS_DNS]:/ efs-test-point
```

`ls -la efs-test-point/`

> 
> file 1.txt must exists
> 
> 
>
4. Configure docker-compose.yml file:

```
services:
  sidekiq:
    volumes:
      - uploads_tmp_efs:/home/application/public/uploads/tmp
  ...
volumes:
  uploads_tmp_efs:
    driver: local
    driver_opts:
      type: nfs
      o: addr=[YOUR_EFS_DNS],nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2
      device: [YOUR_EFS_DNS]:/
```
by default swarm will always look for local volume driver ,so the best way is to

1. create nfs share i.e. `yum -y install nfs-utils`
2. export it in /etc/exports as below,
`/root/nfshare 192.168.1.0/24(rw,sync,no_root_squash)`
3. open required ports, in my case i did below,
`firewall-cmd --permanent --add-service mountd ; firewall-cmd --permanent --add-service rpc-bind ; firewall-cmd --permanent --add-service nfs ; firewall-cmd --zone=public --permanent --add-port 2049/tcp`
4. mount newly created share on docker worker nodes & then
5. `docker service create --name my-web --replicas 3 -p 80:80 --mount 'type=volume,source=nfshare,target=/usr/share/nginx/html/,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/root/nfshare,"volume-opt=o=addr=192.168.1.8,rw"' nginx:latest`
6. in above example i have created nfshare on 192.168.1.8 host & exported using /etc/exports file
7. started daemon(s)
`systemctl start nfs-server rpcbind & systemctl enable nfs-server rpcbind`
8. exportfs -r to changes take effect
9. /root/nfshare have my own index.html
10.check volume-drive entry carefully , it can be external also & whoa it worked for me
10. for more reference <https://docs.docker.com/storage/volumes/>