Package: docker-volume-easyfuse
easyfuse- simple FUSE volume driver for DockerSimple FUSE-based docker volume driver based on the local driver systax. By offloading volume mounting to a simplemount -t fusesubprocess call, the typical problem ofhttps://github.com/moby/moby/issues/27103does not apply.The plugin uses legacy architecture (mounting as a unix socket) to expose to the user full host system capabilites ofmount. This way, user can e.g. fully specifyuidandgidvolume mapping, use local system resources (e.g. SSH keys), something that is an annoying shortcoming of plugins such asvieux/sshfs.Initially, the plugin was developed to allow using SSHFS in scenario, wherevieux/sshfssimply wouldn't work, and after discoveringwhythelocaldriver would not work with fuse mount type. Hovever, in theory this plugin should work with anyfuse-mounted filesystem (and in future, possibly even others).PermissionsCurrently, since easyfuse usesmountfor creating actual fuse volumes,easyfusemust be ran as root. This may change in future versions.Package dependenciesIt's relatively easy to runeasyfusewithout actually installing the package, nevertheless it
requires some non-standard third party Python libraries. To start, simply install module dependencies
(see [requirements.txt]), either withsudo python3 -m pip install -r requirements.txtor (preferably) with your system package manager, e.g. for Debian/Ubuntu:sudo apt install python3-aiohttpWhen usingpip, make sure the packages are installed globally, aseasyfusecurrently needs to be ran as root.Local installation in virtual environmenteasyfuseshould have no problems working out of a python virtual environment.
Simply initialize a virtual environment and install the package locally:$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install -e .This will pull all local requirements, without interfering with the system and system's package
managers.When running from venv withsudo, you may need to manually point to the venv's python as virtual
environment variables are not inherited bysudo-ed process, see:# locally installed aiohttp in version 3.5.1, venv installed aiohttp in version 3.7.3:
(venv) $ python3 -c 'import aiohttp; print(aiohttp.__version__)'
3.7.3
(venv) $ sudo python3 -c 'import aiohttp; print(aiohttp.__version__)'
3.5.1Instead, simply usevenv/bin/pythonexplicitly:(venv) $ sudo venv/bin/python -c 'import aiohttp; print(aiohttp.__version__)'
3.7.3Running manually (without installation)To run in a stand-alone mode (preferred for development), start in the main directory and simply runsudo python3 -m easyfuse -s /run/docker/plugins/easyfuse.sockseepython3 -m easyfuse -h(nosudorequired) for full list of available options.Running withsystemd(with or without installation)systemdfolder contains basic systemd unit files for socket activation, either for global and local
setup.
Assuming/etc/systemd/systemas the configuration path of choice, typical activation for a local setup would be:$ SYSTEMD_UNIT_TARGET=/etc/systemd/system
$ sudo cp systemd/easyfuse.socket $SYSTEMD_UNIT_TARGET/
$ WORKDIR=$PWD envsubst '$WORKDIR' < systemd/easyfuse.service.dev | sudo tee $SYSTEMD_UNIT_TARGET/easyfuse.service
$ sudo systemctl daemon-reload
$ sudo systemctl start easyfuse.socketWhen using virtualenv, use the appropriate config:(venv) $ SYSTEMD_UNIT_TARGET=/etc/systemd/system
(venv) $ sudo cp systemd/easyfuse.socket $SYSTEMD_UNIT_TARGET/
(venv) $ envsubst '$VIRTUAL_ENV' < systemd/easyfuse.service.venv | sudo tee $SYSTEMD_UNIT_TARGET/easyfuse.service
(venv) $ sudo systemctl daemon-reload
(venv) $ sudo systemctl start easyfuse.socketFor a global installation (i.e. if you can callpython3 -m easyfuse -has root from anywhere, without virtual environment), simply use:$ SYSTEMD_UNIT_TARGET=/etc/systemd/system
$ sudo cp systemd/easyfuse.socket  $SYSTEMD_UNIT_TARGET/
$ sudo cp systemd/easyfuse.service $SYSTEMD_UNIT_TARGET/
$ sudo systemctl daemon-reload
$ sudo systemctl start easyfuse.socketAutomatic systemd setupeasyfuseprovides a simple automaticsystemdsetup viaeasyfuse.systemd_setupscript-module.
Seepython3 -m easyfuse.systemd_setup -hfor reference. Remember that when usingsudowithvenv,
you need to use thevenvsymlink instead ofpython3:(venv) $ sudo python3 -m easyfuse.systemd_setup venv          # <- this will install using the global python
(venv) $ sudo venv/bin/python3 -m easyfuse.systemd_setup venv # <- this will install using the local venvUsingeasyfusewith docker volumeNote: when using SSHFS, make sure the host key is accepted by the root user (or whatever user is running the mount command). This can be done by simply doingsudo ssh user@my-ssh-hostand verifying the public key, or withssh-keyscan >> /root/.ssh/known_hosts.$ docker volume create -d easyfuse -o 'o=IdentityFile=$HOME/.ssh/id_ed25519,uid=1000,gid=1000,users,idmap=user,noatime,allow_other,_netdev,reconnect,rw' -o 'device=sshfs#user@my-ssh-host:/my-ssh-volume' my-volume
my-volume$ docker run --rm -it -v my-volume:/my-volume busybox ls /my-volume -lah
total 8K
drwxrwsr-x    1 1000     1000        4.0K Nov 25 00:43 .
drwxr-xr-x    1 root     root        4.0K Nov 25 13:27 ..$ docker volume rm my-volume
my-volumeUsingeasyfusewith docker-composeA fully-featured example with docker-compose can be found in the examples folder. See alsobelow.volumes:
  nfs:
    driver: easyfuse
    driver_opts:
      o: IdentityFile=$PWD/my-secret.key,uid=1000,gid=1000,users,idmap=user,noatime,allow_other,_netdev,reconnect,rw
      device: "sshfs#testuser@localhost:testdir"Test with minimal local sshfs setupFolder examples/mini-sshfs contains a minimal sshd configuration and startup script for your local user that you can use to test the plugin.The scripts assume you have sshd available at /usr/sbin/sshd. This can be easily overriden with SSHD environment variable. To start the server simply issue:examples$ mini-sshfs/run_sshd.shThe script will generate user and host keys and store them locally in the mini-sshfs folder. The server runs at port 2022 (override with MINI_SSHD_PORT environment variable) and binds to localhost interfaces only (127.0.0.1 and ::1). To verify the server works you can check if ssh with the exported known_hosts and user key work:examples$ ssh -o UserKnownHostsFile=mini-sshfs/known_hosts -i mini-sshfs/.keys/ssh_user_ed25519_key -p 2022 $USER@localhost
Last login: Wed Nov 25 00:00:00 2020 from xx.yy.zz.ww

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
$ exit
logout
Connection to localhost closed.
examples$Verify with a regular named volumeexamples$ docker volume create -d easyfuse -o "o=IdentityFile=$PWD/mini-sshfs/.keys/ssh_user_ed25519_key,UserKnownHostsFile=$PWD/mini-sshfs/known_hosts,port=2022,uid=1000,gid=1000,users,idmap=user,noatime,allow_other,_netdev,reconnect,rw" -o "device=sshfs#$USER@localhost:$PWD/test" my-volume
my-volume

examples$ docker run --rm -it -v my-volume:/my-volume busybox ls /my-volume -lah
total 12K
drwxr-xr-x    1 1000     1000        4.0K Nov 25 15:16 .
drwxr-xr-x    1 root     root        4.0K Nov 25 15:45 ..
-rw-r--r--    1 1000     1000         445 Nov 25 15:17 lorem_ipsum.txt

examples$ docker volume rm my-volume
my-volumeVerify with docker-composeexamples$ cat docker-compose.yml
version: '3.4'

services:
  mytest:
    image: alpine
    volumes:
      - 'nas:/nas:rw'
    command: [sh, -c, 'touch /nas/test; ls -lah /nas;']

volumes:
  nas:
    driver: easyfuse
    driver_opts:
      o: IdentityFile=$PWD/mini-sshfs/.keys/ssh_user_ed25519_key,UserKnownHostsFile=$PWD/mini-sshfs/known_hosts,Port=2022,uid=1000,gid=1000,users,idmap=user,noatime,allow_other,_netdev,reconnect,rw
      device: "sshfs#$USER@localhost:$PWD/test"

examples$ docker-compose up
Creating volume "examples_nas" with easyfuse driver
Starting examples_mytest_1 ... done
Attaching to examples_mytest_1
mytest_1  | total 12K
mytest_1  | drwxr-xr-x    1 1000     1000        4.0K Nov 25 16:29 .
mytest_1  | drwxr-xr-x    1 root     root        4.0K Nov 25 16:29 ..
mytest_1  | -rw-r--r--    1 1000     1000         445 Nov 25 15:17 lorem_ipsum.txt
mytest_1  | -rw-r--r--    1 1000     1000           0 Nov 25 16:29 test
examples_mytest_1 exited with code 0

examples$ docker-compose down -v
Removing examples_mytest_1 ... done
Removing network examples_default
Removing volume examples_nas