feat: add multi-module support and custom config mount to rsyncd #3

Merged
dresi merged 1 commits from feat/rsyncd-multi-module into main 2026-06-11 15:21:41 +02:00
2 changed files with 108 additions and 5 deletions

73
rsyncd/README.md Normal file
View File

@ -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 |

View File

@ -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 <<EOF > /etc/rsyncd.conf
if [ ! -f /etc/rsyncd.conf ]; then
cat <<EOF > /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 <<EOF >> /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 <<EOF >> /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 "$@"