Borgmatic Mount Container — Mounting a Remote Borg Backup via Docker
This is a Docker container that uses Borg Backup (via the b3vis/borgmatic image) to mount a remote Borg repository into your local system as a filesystem, using FUSE.
Specifically, this container:
- Connects to a remote Borg repository hosted on a Hetzner Storage Box (
YOUR_BOX_ID.your-storagebox.de) over SSH (port 23). - Uses borg mount to mount the entire contents of the backup archives (snapshots) in that repository into
/mnt/restoreinside the container, which is mapped to/mnt/hetzneron the host (thanks torsharedpropagation). - Lets you browse / restore files from old backups like a regular directory, without extracting the whole backup.
- Authenticates with an SSH private key + the passphrase of the Borg repo (end-to-end encryption).
In short: this is a tool that “opens” a remote backup repository like a disk so you can view/copy the files you need to restore, instead of running borg extract by hand.
⚠️ Note: this container is only for mounting/restoring — it does not run scheduled backups (there is no cron/schedule for
borgmatic createhere).
The docker-compose.yml file
The original file had one line that mixed a tab instead of spaces (restart: unless-stopped), which causes a YAML indentation error in docker compose. The version below has been fixed to use spaces consistently.
💡 Before running anything, replace the placeholders in the compose file with your own values:
YOUR_BOX_ID→ your Hetzner customer number (the one in your Storage Box address)YOUR_BORG_PASSPHRASE→ the passphrase you set when creating the Borg repository
services:
borgmatic:
image: b3vis/borgmatic:2.1.3
container_name: borgmatic
restart: unless-stopped
cap_add:
- SYS_ADMIN
devices:
- /dev/fuse
security_opt:
- apparmor:unconfined
environment:
TZ: Asia/Ho_Chi_Minh
BORG_RSH: "ssh -p 23 -i /root/.ssh/id_ed25519_hetzner -o StrictHostKeyChecking=accept-new"
BORG_REPO: "ssh://YOUR_BOX_ID@YOUR_BOX_ID.your-storagebox.de:23/./backup/0"
BORG_PASSPHRASE: "YOUR_BORG_PASSPHRASE"
volumes:
- /root/.ssh/id_ed25519_hetzner:/root/.ssh/id_ed25519_hetzner:ro
- ./config/keys/YOUR_BOX_ID_your_storagebox_de__backup_0:/root/.config/borg/keys/YOUR_BOX_ID_your_storagebox_de__backup_0:ro
- ./cache:/root/.cache/borg
- /mnt/hetzner:/mnt/restore:rshared
entrypoint: >
sh -c "
mkdir -p /mnt/restore &&
borg mount \$$BORG_REPO /mnt/restore -f
"
Key points explained:
cap_add: SYS_ADMIN+devices: /dev/fuse+apparmor:unconfined→ the required trio for the container to use FUSE (the foundation ofborg mount).BORG_RSH→ specifies the SSH key and the Storage Box’s port 23;accept-newautomatically accepts the host key on first contact.rsharedon the mount volume → so the FUSE mount inside the container propagates out to the host.\$$BORG_REPO→$$is how you escape$in compose, soBORG_REPOis resolved by the container rather than by compose.-f→ keeps the mount running in the foreground, keeping the container in a running state.
Installation guide
Step 1 — Create the directory structure
mkdir -p ~/docker/borgmatic/config/keys
mkdir -p ~/docker/borgmatic/cache
cd ~/docker/borgmatic
Explanation:
config/keys→ where the encryption key file of the Borg repository lives (required if the repo useskeyfileencryption).cache→ where Borg stores its metadata cache (makes mounting/listing faster, avoids re-downloading the whole index every time).
Step 2 — Prepare the SSH key
You need an SSH private key for connecting to the Hetzner Storage Box:
ls -la /root/.ssh/id_ed25519_hetzner
If you don’t have one yet, generate a key and add the public key to the Hetzner Storage Box (via the Hetzner panel):
ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519_hetzner -N ""
Then copy the public key (id_ed25519_hetzner.pub) into the SSH keys section of the Hetzner Storage Box control panel.
Step 3 — Copy the Borg repo key file (if the repo uses keyfile encryption)
If the repository was created with --encryption keyfile (not repokey), you need to copy the corresponding key file to:
~/docker/borgmatic/config/keys/YOUR_BOX_ID_your_storagebox_de__backup_0
This file is usually located in ~/.config/borg/keys/ on the machine that originally initialized the repository. If you use repokey (key stored in the repo, no separate file), you can skip this step and remove the corresponding key volume mount line from the compose file.
Step 4 — Create the docker-compose.yml file
nano ~/docker/borgmatic/docker-compose.yml
Paste the indentation-fixed content from above and save it.
⚠️ Security: it’s recommended to move
BORG_PASSPHRASEinto a.envfile instead of hardcoding it in the compose file, for example:
echo "BORG_PASSPHRASE=YOUR_BORG_PASSPHRASE" > ~/docker/borgmatic/.env
and in the compose file use:
environment:
BORG_PASSPHRASE: "${BORG_PASSPHRASE}"
Step 5 — Create the mount directory on the host
sudo mkdir -p /mnt/hetzner
Step 6 — Start the container
cd ~/docker/borgmatic
docker compose up -d
Step 7 — Verify
docker logs -f borgmatic
If the mount succeeded, you’ll see the backup archives appear as subdirectories at:
ls /mnt/hetzner
Each subdirectory corresponds to an archive (snapshot) — you can cd into them to browse and copy the files you need to restore.
Step 8 — Unmount when you’re done
docker compose down
(since the entrypoint runs borg mount -f in the foreground, stopping the container automatically unmounts).
Notes
- This container is strictly for mount/restore purposes. If you also need scheduled automatic backups (running
borgmatic createon a cron schedule), the next step is to write aconfig.yamlfor borgmatic — replacing the mount entrypoint with the image’s service mode. - Keep the
cachedirectory between runs so subsequent mounts are faster; only delete it if you suspect the cache is corrupted.
See also: