Sync a volume of two containers in real time, across the globe!
What can I do with this? Create a sender and attach the volume you want to sync in real time, then create a receiver on the other side of the world and attach another volume. Both the sender volume will now be synced in real time on any file changes with the receiver volume via rsync. Since the sender can use any networking available to it, this works via Wireguard, Tailscale, Zerotier, you name it.
This image can help you synchronize your Traefik configuration in a HA pair or your Nginx www data as well as any other configuration or variable files for high-available file-based setups and configurations. Sync your Traefik ACME generated certs between multiple Traefik nodes.
The sync direction is unidirectional, from sender to receiver. It will also delete all files in the receiver which are not present in the sender!
Since inotifyd is used to watch a directory and all files within, the sender container will spawn an inotifyd for each subfolder (recursive). If you have 200 subfolders, this will result in 200 inotifyd processes running in the sender! This image is not meant to sync thousands of files, there are better solutions for this which don’t work in realtime. Realtime file sync is very expensive in terms of CPU cycles and network bandwidth. Use with care!
If you need to synchronize multiple volumes, use this image multiple times.
- /rsync - Directory of the volume that will be synced. Simply attach your volume to this path on both receiver and sender
services:
receiver:
image: "11notes/volume-rsync"
container_name: "receiver"
command: ["receiver"]
environment:
TZ: Europe/Zurich
SSH_PORT: 2222
SSH_AUTHORIZED_KEY: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoR1q9aW+tGwQJLV1Yx23xHPDxtg3QnGhBlVoXFYmqZ
SSH_HOST_KEY: |-
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCVvFZeNXWqIVpyVjZTzig0g5xCNkwWL4NRL5YBsWTIkQAAAJjiM55K4jOe
SgAAAAtzc2gtZWQyNTUxOQAAACCVvFZeNXWqIVpyVjZTzig0g5xCNkwWL4NRL5YBsWTIkQ
AAAEC68u0POEIVVWNw3dsUs4qOFmub3JL66ehRQZUfV8Qfq5W8Vl41daohWnJWNlPOKDSD
nEI2TBYvg1EvlgGxZMiRAAAAEXJvb3RAYzFkNmZkODYyY2UzAQIDBA==
-----END OPENSSH PRIVATE KEY-----
volumes:
- "receiver:/rsync"
networks:
- "rsync"
restart: always
sender:
image: "11notes/volume-rsync"
container_name: "sender"
depends_on:
receiver:
condition: service_healthy
restart: true
command: ["sender"]
environment:
DEBUG: true
TZ: Europe/Zurich
SSH_HOST: receiver
SSH_PORT: 2222
SSH_KNOWN_HOSTS: receiver ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJW8Vl41daohWnJWNlPOKDSDnEI2TBYvg1EvlgGxZMiR
SSH_PRIVATE_KEY: |-
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACAqEdavWlvrRsECS1dWMdt8Rzw8bYN0JxoQZVaFxWJqmQAAAJiEAwhChAMI
QgAAAAtzc2gtZWQyNTUxOQAAACAqEdavWlvrRsECS1dWMdt8Rzw8bYN0JxoQZVaFxWJqmQ
AAAEAIchARmgWd/hZQVvk0MZKTizC50zj89vsQRTSXsvKnFSoR1q9aW+tGwQJLV1Yx23xH
PDxtg3QnGhBlVoXFYmqZAAAAEXJvb3RAZGUxYzU4ZTA0NTc2AQIDBA==
-----END OPENSSH PRIVATE KEY-----
RSYNC_TRANSFER_DELAY: 5
volumes:
- "sender:/rsync"
networks:
- "rsync"
restart: always
volumes:
receiver:
sender:
networks:
rsync:
internal: true
Parameter | Value | Description |
---|---|---|
user |
docker | user docker |
uid |
1000 | user id 1000 |
gid |
1000 | group id 1000 |
home |
/rsync | home directory of user docker |
Parameter | Value | Default |
---|---|---|
TZ |
Time Zone | |
DEBUG |
Show debug information | |
RECEIVER:SSH_PORT |
TCP port of SSH daemon | 22 |
RECEIVER:SSH_AUTHORIZED_KEY |
The public SSH key of the sender | |
RECEIVER:SSH_HOST_KEY |
The host key used for the SSH daemon | |
SENDER:MASK |
The mask used for inotifyd | cdnym |
SENDER:SSH_HOST |
The receiver IP or FQDN | |
SENDER:SSH_PORT |
TCP port of receiver SSH daemon | 22 |
SENDER:SSH_KNOWN_HOSTS |
The public key of the receivers SSH daemon (correlates to RECEIVER:SSH_HOST_KEY) | |
SENDER:SSH_PRIVATE_KEY |
The private key of the sender (correlates to RECEIVER:SSH_AUTHORIZED_KEY) | |
SENDER:RSYNC_TRANSFER_DELAY |
The delay in seconds between file events and the actual transfer (timeout) | 0 |
- Use a reverse proxy like Traefik, Nginx to terminate TLS with a valid certificate
- Use Let’s Encrypt certificates to protect your SSL endpoints
This image is provided to you at your own risk. Always make backups before updating an image to a new version. Check the changelog for breaking changes. You can find all my repositories on github.