Utilizing the rclone Docker Volume Driver with Backblaze B2

What is the problem you are having with rclone?

I'm attempting to mount a Backblaze B2 bucket to a Docker volume using the rclone volume driver for Docker

Run the command 'rclone version' and share the full output of the command.

On the machine I'm using, this is the full output:
rclone v1.61.1

  • os/version: Microsoft Windows 10 Pro 22H2 (64 bit)
  • os/kernel: 10.0.19045.2788 (x86_64)
  • os/type: windows
  • os/arch: amd64
  • go/version: go1.19.4
  • go/linking: static
  • go/tags: cmount

However, I think this is irrelevant as this would be in relation to the rclone Docker volume driver that I'm having issues with. As for that one, I'm using the "arm64" tag for the latest in that line. As for why arm64, this is because I am attempting to deploy this to a docker swarm cluster powered by Raspberry Pis.

Which cloud storage system are you using? (eg Google Drive)

Backblaze B2

The command you were trying to run (eg rclone copy /tmp remote:tmp)

docker volume create test -d rclone -o type=b2 -o b2-account=[REDACTED] -o b2-key=[REDACTED]

The rclone config contents with secrets removed.

N/A

A log from the command with the -vv flag

N/A

While the command listed above does create a volume, whatever container I attach to the volume isn't able to access the B2 bucket and anything I have the container write in volume does not sync to the cloud storage. I think my problem is that I'm either not using the correct (or enough) option flags to define the volume in the way the driver wants, but I'm unable to find any definitive documentation on the website explaining what flags need to be set for this specific situation (or any situation honestly beyond the one test case on the site regarding SFTP integration). If there is an alternative way I should be seeking support for the docker volume driver, please let me know.

As a first step to solving this, I tried to get the Docker Volume Plugin working on my Mac. I had to go down the rabbit hole somewhat to do so, and I'm sharing what I found here in case it helps point the way for you on the Raspberry Pi and, frankly, because it took me several hours to figure all this out and I need to post it somewhere!

The rclone Docker Volume Plugin doc instructs you to create a pair of directories on the host:

% sudo mkdir -p /var/lib/docker-plugins/rclone/config
% sudo mkdir -p /var/lib/docker-plugins/rclone/cache

I did so, and tried to install the plugin, but:

% docker plugin install rclone/docker-volume-rclone args="-v" --alias rclone --grant-all-permissions 
latest: Pulling from rclone/docker-volume-rclone
Digest: sha256:fd1396468c3b3613081a1b10a2b4173219f9b3d43b2aedceab6830c84d821094
c3ef44c55cda: Complete 
Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting "/var/lib/docker-plugins/rclone/config" to rootfs at "/data/config": stat /var/lib/docker-plugins/rclone/config: no such file or directory: unknown

The problem is that the Mac is not the Docker host. The Docker host is a Linux instance running in a VM. This Linux instance has its own filesystem that overlaps with the Mac filesystem in some places, but not in others. In particular, /var on the Mac is not the same as /var on the Docker host.

If you don't see this error, then Docker on the Raspberry Pi likely uses the Pi's Linux OS as the host, but read on, there's more...

When Docker installs the plugin, it tries to mount the host's /var/lib/docker-plugins/rclone/config directory as /data/config in the plugin, and fails, since that directory does not exist on the host. There is a workaround, though. On the Mac, /var is a soft link to /private/var, and the Mac's /private directory is accessible from the host, and therefore the plugin.

Following advice here, I uninstalled and reinstalled the plugin, configuring it to use the /private directories for its config and cache:

% docker plugin install rclone/docker-volume-rclone:arm64 \
       --alias rclone --grant-all-permissions \
       args="-v --allow-other" \
       config="/private/var/lib/docker-plugins/rclone/config" \
       cache="/private/var/lib/docker-plugins/rclone/cache"

This allowed the plugin to install cleanly; the next step was to create a volume, using the exact same command that you used:

% docker volume create test -d rclone -o type=b2 -o b2-account=${B2_APPLICATION_KEY_ID} -o b2-key=${B2_APPLICATION_KEY}
Error response from daemon: create test: VolumeDriver.Create: failed to save state: open /data/cache/docker-plugin.state: operation not permitted

Now the issue is that, even though the host has made the config and cache directories available to the plugin, the plugin can't write to them, since the Linux host runs as the current user rather than as root.

If you didn't see this error, then the plugin is able to write its state file, so the following fix won't apply to you.

It turned out that the fix was easy - change the owner of the plugin's directories to the current user:

sudo chown $(whoami):staff /var/lib/docker-plugins/rclone/config
sudo chown $(whoami):staff /var/lib/docker-plugins/rclone/cache

After removing the test volume, I was able to use the same command as in your post to create a volume and then access it without any problems:

% docker volume create test -d rclone -o type=b2 -o b2-account=${B2_APPLICATION_KEY_ID} -o b2-key=${B2_APPLICATION_KEY}
test
% docker run --rm -it -v test:/mnt --workdir /mnt ubuntu:latest bash
root@eee9adc6b4ad:/mnt# ls
...all the buckets in my B2 account...
root@eee9adc6b4ad:/mnt# cat metadaddy-public/hello.txt 
Hello from US West
root@eee9adc6b4ad:/mnt# echo 'Hello from docker' > metadaddy-public/docker.txt

Check it out: https://f004.backblazeb2.com/file/metadaddy-public/docker.txt

So, we know that your docker volume create command works just fine, and the problem must lie elsewhere.

One more diagnostic: from the Mac command line, I can see the plugin's state file, and read its contents:

% ls -l /var/lib/docker-plugins/rclone/cache
total 8
-rw-------  1 ppatterson  staff  279 Apr 28 14:20 docker-plugin.state
% cat /var/lib/docker-plugins/rclone/cache/docker-plugin.state | jq . 
[
  {
    "name": "test",
    "mountpoint": "/mnt/test",
    "created": "2023-04-28T21:20:28.892544708Z",
    "fs": "",
    "type": "b2",
    "options": {
      "b2-account": "*****",
      "b2-key": "*****"
    },
    "mounts": [
      "f8a9355b3ec90a13a6244583c4ae735b794c0741dfa72a9230680c7fe134ea36"
    ]
  }
]

Now that I have it working on my Mac, I'll pull out a Raspberry Pi and try it there.

What version of RPi are you using, and what OS/Docker versions are you running on it?

I didn't run into any of the errors you ran into during setup. I'm using Raspberry Pi 4 on Raspberry Pi OS Lite (64-bit). However, through your code blocks, I realized the idiotic mistake I was making (I'm relatively new to cloud storage). I forgot I had to specify the bucket whenever I was testing things out which likely was the problem I was encountering. With this in mind, I should be able to set up what I was hoping to accomplish and I thank you for your help.
Additionally, I don't know if this was intentional, but your last code block lists your b2-account and b2-key fully. Just wanted to point that out in case you want to edit those out of the reply or remove that application key from your B2 account if you haven't already.

Oops - I just deleted that key - thanks for the heads up. Thankfully, there's nothing of any value in that account - just my demo buckets.

Let me know how it goes - I'm always happy to help with anything B2-related!

30 minutes into further research and I'm left with more questions.
Because docker can be... docker about volumes, is there an option flag that can be used to specify the bucket or something I can do on B2's side so that when the volume is utilized, it directly goes to the bucket and doesn't start on the "root".

Yep - use -o path=<bucketname>/<optional-path> when you create the volume - e.g.:

Specify the bucket:

% docker volume create test -d rclone -o type=b2 \
    -o b2-account=${B2_APPLICATION_KEY_ID} \
    -o b2-key=${B2_APPLICATION_KEY} \
    -o path=metadaddy-public
test
% docker run --rm -it -v test:/mnt --workdir /mnt ubuntu:latest bash
root@2df2c582f58b:/mnt# ls
hello.txt   docker.txt   static
root@9a176d7ae84f:/mnt# cat hello.txt 
Hello from US West
root@9a176d7ae84f:/mnt# exit

or a path within the bucket:

% docker volume rm test                                             
test
% docker volume create test -d rclone -o type=b2 \
    -o b2-account=${B2_APPLICATION_KEY_ID} \
    -o b2-key=${B2_APPLICATION_KEY} \
    -o path=metadaddy-public/static
test
% docker run --rm -it -v test:/mnt --workdir /mnt ubuntu:latest bash
root@9a176d7ae84f:/mnt# ls
css  images

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.