NFS share not mounting as volume, but fine manually

Facts:

  • Docker Engine 29.1.3 running on Alpine x86_64
  • NFS share available via OpenMediaVault
  • Docker Swarm with 3 nodes (1 Master, 2 workers)
  • All nodes are dual-stack with static IPs
  • All Hostnames are resolvable, all reverse lookups exist

I’m trying to deploy Portainer using the default YAML for a Swarm, with the addition of these lines for the data volume:

volumes:
  portainer_data:
    driver: local
    driver_opts:
      type: "nfs"
      o: "rw,soft,vers=4.2,clientaddr=swarm01.domain,clientaddr=swarm02.domain,clientaddr=swarm03.domain"
      device: "omv.domain:/docker/portainer"

This however fails with an unspecified “invalid argument” error.

Manually mounting the path works:

mount omv.domain:/docker/portainer /var/lib/docker/volumes/portainer_portainer_data/_data \
-o rw,soft,vers=4.2,clientaddr=swarm01.domain,clientaddr=swarm02.domain,clientaddr=swarm03.domain

None of the logs provide any insight as to what exactly is the problem. Even when the options were reduced to rw,soft it still failed.

volume inspect:

[
    {
        "CreatedAt": "2026-03-03T14:25:25Z",
        "Driver": "local",
        "Labels": {
            "com.docker.stack.namespace": "portainer"
        },
        "Mountpoint": "/var/lib/docker/volumes/portainer_portainer_data/_data",
        "Name": "portainer_portainer_data",
        "Options": {
            "device": "omv.domain:/docker/portainer",
            "o": "rw,soft,vers=4.2,clientaddr=swarm01.domain,clientaddr=swarm02.domain,clientaddr=swarm03.domain",
            "type": "nfs"
        },
        "Scope": "local"
    }
]

Any help would be appreciated.

Try to declare your volume like this:

volumes:
  portainer_data:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=omv.domain,nfsvers=4.2,soft"
      device: ":/docker/portainer"

I removed rw as it’s the default behavior., and clientaddr is not used with nfs 4.2 (or 4.1). I am not entirely sure, if addr can actually be a hostname, or must be an ip, and if nfsvers can allow 4.2, or if it only allows 4.

That “helped” insofar as it’s now a different problem, operation not supported.

volume inspect:

        "Options": {
            "device": ":/docker/portainer",
            "o": "soft,addr=omv.domain",
            "type": "nfs"
        },

Guess I’ll just put it in /etc/fstab and bind-mount from there.

Managed to get it working with these settings:

volumes:
  portainer_data:
    driver: local
    driver_opts:
      type: "nfs"
      o: "soft,clientaddr=swarm01.domain,clientaddr=swarm02.domain,clientaddr=swarm03.domain,addr=OMV_IPV4,addr=OMV_IPV6,vers=4.2"
      device: "omv.domain:/docker/portainer"

Interesting to see that those arguments are supported.

The man page to nfs says this to clientaddr:

          NFS protocol versions 4.1 and 4.2 use the client-
          established TCP connection for callback requests, so do not
          require the server to connect to the client.  This option
          is therefore only affect NFS version 4.0 mounts.

I have never used a domain or ip in device and haven’t seen it used somewhere.

The compose file reference even shows it in the description for driver_opts:

Glad it works!

Update: I was curious about the difference of nfsvers and vers:

   nfsvers=n
          The NFS protocol version number used to contact the
          server's NFS service.  If the server does not support the
          requested version, the mount request fails.  If this option
          is not specified, the client tries version 4.2 first, then
          negotiates down until it finds a version supported by the
          server.

   vers=n This option is an alternative to the nfsvers option.  It is
          included for compatibility with other operating systems

Source: nfs(5) - Linux manual page

The addr attribute is not mentioned in the docs. It seems to be an attribute the mount command implicitly adds (or gets added by nfs) when a share is mounted, but apparently not added for nfs-backed volumes.