One of the most needed feature to run a docker swarm is to manage volumes the most automatic way, so the orchestration is easier & cleaner.
Bind volumes are not a proper solution because it forces the swarm administrator to enable the same bind on every single node (or defining a label for bind enabled nodes and then restrict services by labels, not a clean solution neither).
Docker volume drivers
Docker supports more options than bind volumes or local volumes, one of the simpler drivers (at least because NFS is quite easy to be available and because docker deploys this driver in its core) is the NFS driver.
First of all an NFS share is needed, usually an IP address and a NFS share path, for instance IP
184.108.40.206 and share name
Ensure NFS client is installed in every node (typically is installed), for instance for Ubuntu:
sudo apt-get install -y nfs-common
Then inside the
docker-compose.yml two things are required:
- First define a named volume at service as usual.
- Define a volume at
nfsvolume type and passing the options to point to the NFS share.
Let’s create a simple MariaDB service persisting data into a NFS volume, so it’s OK for the orchestrator to deploy the service in any of the nodes:
version: '3.7' services: mariadb: image: mariadb:10.4.12 environment: - MYSQL_USER=user - MYSQL_PASSWORD=password - MYSQL_ROOT_PASSWORD=password - MYSQL_DATABASE=db volumes: - type: volume source: mariadb_data target: /var/lib/mysql volumes: mariadb_data: driver_opts: type: 'nfs' o: 'addr=220.127.116.11,nolock,soft,rw' device: ':/nfs/data-volume'
Several things could happen depending on your NFS configuration.
It could happen that your NFS share is always accessible by an special user and any other user & group accessing it will generate invalid accesses. You can avoid this running the service with user ID and group ID of the NFS share.
... services: mariadb: image: mariadb:10.4.12 user: 501:1000 ...
Disable copying data from container to volume
By default when you create a volume into a path in which the container has data, this data will be copied into the volume, you can avoid that (maybe you have more permission errors) with the
... services: mariadb: image: mariadb:10.4.12 ... volumes: - type: volume source: mariadb_data target: /var/lib/mysql volume: nocopy: true ...