Categories
Containerization DevOps SysAdmin

ConFusion

Containerized Fusion

Mount volumes on your host machine with Docker Compose and Rclone’s official image via FUSE — without the need for Docker plugins or building images to add S6 overlays.

Introduction

When it comes to mounting remote storage as local volumes via a Docker container with Rclone, your choices are generally limited to Rclone’s Docker Image in conjunction with Rclone’s Docker plugin for Docker volumes (I had difficulty with host volumes and didn’t want to be limited to named volumes like Rclone’s instructions use [1]Docker Volumes: Why, When, and Which Ones?) or a third-party Rclone Docker image that uses the S6 overlay. With inspiration from Kenny Deckers‘ article, Mount a Google Drive folder on a local server using a Rclone docker container, I was able to achieve desired results with an ugly, stupid hack beautiful, intellectual engineering of a shell script for unmounting when the container is stopped and since Docker Compose doesn’t have event hooks — which have been repeatedly requested. [2]Add pre/post command option [3]Hooks/ Plugins support to run arbitrary scripts [4]Proposal: docker-compose events [5]Hooks to run scripts on host before starting any containers [6]Event Hooks in Compose [7]Setting pre-hook for docker-compose file

Prerequisites

Setup

Rclone entry point

When examining Rclone’s Dockerfile, you’ll see that the Rclone binary is the entry point. With Docker Compose, I override the entry point with the following script and then pass commands to it. When a SIGTERM or SIGINT (Ctrl + C) is received, it will use an exit trap to pass a SIGTERM to the child process, Rclone, and then attempt to unmount the mount point that was passed in as the second argument.

Why are you modifying the entry point?

To employ the use of an exit trap.

What is the difference between an entry point and a command?

This won’t be an article about the difference between those directives, but both will be altered via Docker Compose.

Pray I don’t alter it any further.

That line is catchy, I’m going to start using it!

/srv/rclone/entrypoint.sh

#!/usr/bin/env sh

# ConFusion: Containerized Fusion with Rclone, FUSE, and Docker Compose
# https://LTG.FYI/ConFusion
# Louis T. Getterman IV
  
remotePoint="$1"
mountPoint="$2"
  
__cleanup() {
    kill -TERM "$child" 2>/dev/null
    umount "${mountPoint}" || true
    rmdir "${mountPoint}" || true
}
  
trap __cleanup SIGTERM
trap __cleanup SIGINT

# Create the directory for the mount point.
mkdir --parents "${mountPoint}"
  
# Mount Docker Command passed in from Docker Compose.
rclone mount "${remotePoint}" "${mountPoint}" &
child=$!
  
# Rclone started, wait on it, and clean-up when stopped.
wait "$child"

Docker Compose

/etc/docker/compose/infrastructure/docker-compose.yaml

Perhaps you want to mount a cloud service such as Google Drive or Dropbox, and SFTP or WebDAV from your own file server? You’re not limited to a single mount, and can add mounts by copying and pasting the following service as additional services that use individual names and commands — be sure to leave the entry point the same.

services:

    rclone:
        container_name: Rclone-MyRemote
        image: rclone/rclone:latest
        restart: always

        entrypoint: "sh /entrypoint.sh"
        command: "myRemote:/some/path/here/ /data/my-remote"

        # Assuming that you run Rclone as the root user with the root group - https://forum.rclone.org/t/defaults-root-file-section/9083/8
        # If it's as another user on the host side, use `id --user` and `id --group` to obtain the appropriate values.
        user: 0:0

        devices:
            - "/dev/fuse"

        cap_add:
            - "SYS_ADMIN"

        security_opt:
            - "apparmor:unconfined"

        volumes:
            - "/srv/rclone/entrypoint.sh:/entrypoint.sh"
            - "/srv/rclone/config:/config/rclone"
            - "/srv/rclone/data:/data:shared"
            - "/etc/passwd:/etc/passwd:ro"
            - "/etc/group:/etc/group:ro"

Configure

Rclone

You’re now ready to create (or modify) your Rclone configuration with the following command. I’ll explain what’s happening here:

  • Docker Compose is running with the configuration file that you saved from above.
  • Upon completion, the container will be removed.
  • Since the entry point is overriding the default as specified in docker-compose.yaml, we need to override our override to return back to the original.
  • Only the “rclone” service that’s defined in the Docker Compose file should be run.
  • The command to pass to the entry point (Rclone’s binary) to run an interactive configuration session.
docker-compose \
    --file /etc/docker/compose/infrastructure/docker-compose.yaml \
    run \
        --rm \
        --entrypoint rclone \
        rclone \
            config \
;

systemd

Now you’re ready to mount your remote volume(s) to your host from the comfort of a Docker container:

systemctl start docker-compose@infrastructure

At the host level, you can access and modify the contents of a mounted volume:

ls -l /srv/rclone/data/my-remote/

When you’re ready to unmount your remote volume(s):

systemctl stop docker-compose@infrastructure

To enable mounting at boot:

systemctl enable docker-compose@infrastructure

To disable mounting at boot:

systemctl disable docker-compose@infrastructure

See also

External links

References


Did this article save you time or money? I'd love a coffee!

Did you find this useful?
Please share with those who you believe would find this useful too!

Leave a Reply

Your email address will not be published.