Ansible tasks to automate rclone docker plugin volume creation

Hi,

I have been using the rclone docker volume plugin to attach a SFTP rclone volume (connecting to my remote torrent client) directly to the arrs containers (lidarr, radarr, sonarr, etc) hosted locally. The plugin has really been a gift and joy to use, and has allowed me to import files from the remote client, easily.

One thing to note, rclone volumes do not like to reconnect once connection is lost (say if you've taken your server down and put it back online). Your containers will come back up (provided you don't have the healthcheck checking volume connection status) and you'll have no actual connection to your remote server. This differs from NFS docker volumes and others which will successfully reconnect in such situations. To regain connection it's best to remove and remake the volume.

To automate everything, I made some rclone ansible tasks I include with my arrs docker stack.

Variables:

Docker RClone volume parameters:

(I refer to mine as downloads_volume, adjust your vars/tasks to suit)

downloads_volume: 'qbittorrent_rclone'  ## name of the volume
downloads_volume_type: 'sftp'  ## ... rclone provider type
downloads_volume_mount_path: '/data/torrents/completed'  ## remote path you want accessible
downloads_volume_host: ''  ## domain of the remote host.

Rclone global flags: Set your global flags/arguments here (including metrics and such)

rclone_docker_plugin_global_args: "--rc --rc-web-gui --rc-web-gui-update"

Tasks:

Cleanup existing volume (recommended since rclone doesn't like reconnecting as mentioned above):

- name: Register downloads volume
  community.docker.docker_volume_info:
    name: '{{ downloads_volume }}'
  register: downloads_volume_result

- name: Remove existing downloads volume
  when: downloads_volume_result.exists
  community.docker.docker_volume:
    name: '{{ downloads_volume }}'
    state: absent
  register: remove_download_volume
  retries: 5
  delay: 10
  until: remove_download_volume is succeeded

Install fuse3:

- name: Install FUSE driver prerequisite
  when: ansible_os_family == 'Debian'
  ansible.builtin.apt:
    name: fuse3

Create the required rclone plugin directories:

- name: Create two directories required by rclone docker plugin
  ansible.builtin.file:
    path: '{{ item }}'
    state: directory
    owner: '{{ puid }}'
    group: '{{ pgid }}'
    mode: '0755'
  loop:
    - /var/lib/docker-plugins/rclone/config
    - /var/lib/docker-plugins/rclone/cache

Check for an existing rclone.conf and touch an empty one if none exists (I leave mine empty when using the volume plugin):

- name: Check if rclone.conf exists
  ansible.builtin.stat:
    path: /var/lib/docker-plugins/rclone/config/rclone.conf
  register: rclone_config_result

- name: Create rclone.conf file
  when: not rclone_config_result.stat.exists
  ansible.builtin.file:
    path: /var/lib/docker-plugins/rclone/config/rclone.conf
    state: touch
    owner: '{{ puid }}'  ## adjust to your user
    group: '{{ pgid }}'
    mode: '0644'

The meat and potatoes: Installing the rclone docker volume plugin and setting global args:

- name: Remove stale docker-plugin.state file
  ansible.builtin.file:
    path: /var/lib/docker-plugins/rclone/cache/docker-plugin.state
    state: absent

- name: Install docker volume rclone plugin
  community.docker.docker_plugin:
    plugin_name: rclone/docker-volume-rclone:latest
    alias: rclone
    state: present

- name: Disable docker volume rclone plugin
  community.docker.docker_plugin:
    plugin_name: rclone
    state: disable

- name: Apply rclone docker plugin global arguments
  ansible.builtin.command: 'docker plugin set rclone RCLONE_VERBOSE=2 args={{ rclone_docker_plugin_global_args | quote }}'

- name: Enable docker volume rclone plugin
  community.docker.docker_plugin:
    plugin_name: rclone
    debug: true
    state: enable

Creating the docker rclone volume:

- name: Create downloads volume
  community.docker.docker_volume:
    name: '{{ downloads_volume }}'
    driver: rclone
    driver_options:
      type: '{{ downloads_volume_type }}'
      path: '{{ downloads_volume_mount_path }}'
      sftp-host: '{{ downloads_volume_host }}'
      sftp-user: '{{ downloads_volume_user }}'
      sftp-pass: '{{ downloads_volume_pass }}'
      allow_other: 'true'
      vfs_cache_mode: 'off'  ## adjust to your required options / needs

The above is essentially an automation of the steps listed here, plus some additional steps added through trial and error of running the rclone docker volume over time.

How you incorporate the steps is up to you. I like having them as a sub_tasks in my arrs role, but you could run them as a pre_task if multiple roles depend on it. Main thing to remember is the inability of the volume to reconnect and the potential of deleting the volume while there are still services running that depend on it. Hence, I have this one volume that is removed recreated as the dependent services are removed and recreated themselves. I find this leads to less issues and frustrations.

Enjoy