From 357ace62e1fe9e334b1b013213ddfadd0eae8029 Mon Sep 17 00:00:00 2001 From: dresi Date: Thu, 11 Jun 2026 14:37:06 +0200 Subject: [PATCH] feat: add multi-module support and custom config mount to rsyncd --- rsyncd/README.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ rsyncd/run.sh | 40 ++++++++++++++++++++++---- 2 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 rsyncd/README.md diff --git a/rsyncd/README.md b/rsyncd/README.md new file mode 100644 index 0000000..d4153b5 --- /dev/null +++ b/rsyncd/README.md @@ -0,0 +1,73 @@ +# rsyncd + +Simple rsync server running in a Docker container. + +Image: `harbor.lan/tools/rsyncd:latest` + +## Usage modes + +### 1. Custom config (mount rsyncd.conf) + +If `/etc/rsyncd.conf` is mounted, the container uses it as-is — no env vars needed. + +```yaml +services: + rsyncd: + image: harbor.lan/tools/rsyncd:latest + ports: + - "873:873" + volumes: + - ./rsyncd.conf:/etc/rsyncd.conf:ro + - /srv/backup:/data +``` + +### 2. Multiple modules via env vars + +Modules are defined via `MODULE_1_*`, `MODULE_2_*`, `MODULE_3_*` etc. — add as many as needed, as long as the numbering is consecutive. + +```yaml +services: + rsyncd: + image: harbor.lan/tools/rsyncd:latest + ports: + - "873:873" + environment: + - ALLOW=10.0.0.0/8 + - MODULE_1_NAME=backup + - MODULE_1_PATH=/data/backup + - MODULE_2_NAME=media + - MODULE_2_PATH=/data/media + - MODULE_2_ALLOW=192.168.1.0/24 + volumes: + - /srv/backup:/data/backup + - /srv/media:/data/media +``` + +### 3. Single module (simple) + +```yaml +services: + rsyncd: + image: harbor.lan/tools/rsyncd:latest + ports: + - "873:873" + environment: + - VOLUME=backup + - ALLOW=10.0.0.0/8 + - OWNER=1000 + - GROUP=1000 + volumes: + - /srv/backup:/volume +``` + +## Environment variables + +| Variable | Default | Description | +|---|---|---| +| `VOLUME` | `volume` | Module name (single-module mode) | +| `ALLOW` | `192.168.0.0/16 172.16.0.0/12` | Allowed IP ranges (global default) | +| `OWNER` | `nobody` | UID for created files | +| `GROUP` | `nogroup` | GID for created files | +| `MODULE_x_NAME` | — | Module name (multi-module mode) | +| `MODULE_x_PATH` | `/volume_x` | Path for module x | +| `MODULE_x_ALLOW` | `$ALLOW` | Allowed IPs for module x | diff --git a/rsyncd/run.sh b/rsyncd/run.sh index 4467fb1..941530d 100644 --- a/rsyncd/run.sh +++ b/rsyncd/run.sh @@ -1,23 +1,51 @@ #!/bin/bash -VOLUME=${VOLUME:-"volume"} ALLOW=${ALLOW:-192.168.0.0/16 172.16.0.0/12} OWNER=${OWNER:-nobody} GROUP=${GROUP:-nogroup} -# create users matching ids passed if necessary if [ "${GROUP}" != "nogroup" ]; then - groupadd -g ${GROUP} rsyncdgroup + groupadd -g "${GROUP}" rsyncdgroup 2>/dev/null fi if [ "${OWNER}" != "nobody" ]; then - groupadd -u ${OWNER} -G rsyncdgroup rsyncduser + useradd -u "${OWNER}" -G rsyncdgroup rsyncduser 2>/dev/null fi -[ -f /etc/rsyncd.conf ] || cat < /etc/rsyncd.conf +if [ ! -f /etc/rsyncd.conf ]; then + cat < /etc/rsyncd.conf uid = ${OWNER} gid = ${GROUP} use chroot = yes pid file = /var/run/rsyncd.pid log file = /dev/stdout +EOF + + # multi-module mode: MODULE_1_NAME, MODULE_1_PATH, MODULE_1_ALLOW, ... + i=1 + while true; do + name_var="MODULE_${i}_NAME" + path_var="MODULE_${i}_PATH" + allow_var="MODULE_${i}_ALLOW" + name="${!name_var}" + [ -z "${name}" ] && break + path="${!path_var:-/volume_${i}}" + allow="${!allow_var:-${ALLOW}}" + cat <> /etc/rsyncd.conf + +[${name}] + hosts deny = * + hosts allow = ${allow} + read only = false + path = ${path} + comment = ${name} +EOF + i=$((i + 1)) + done + + # single-module fallback: VOLUME env var + if [ "${i}" -eq 1 ]; then + VOLUME=${VOLUME:-volume} + cat <> /etc/rsyncd.conf + [${VOLUME}] hosts deny = * hosts allow = ${ALLOW} @@ -25,5 +53,7 @@ log file = /dev/stdout path = /volume comment = ${VOLUME} EOF + fi +fi exec /usr/bin/rsync --no-detach --daemon --config /etc/rsyncd.conf "$@" -- 2.45.2