- Shell 94.1%
- Dockerfile 5.9%
| .forgejo/workflows | ||
| config | ||
| deploy/kubernetes | ||
| rootfs | ||
| .cursorignore | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| README.md | ||
| renovate.json | ||
docker-smb-rclone
Samba file share in Docker (Alpine), with optional per-remote rclone jobs (sync or FUSE mount) under /data.
Quick start
cp .env.example .env
# edit SMB_USER / SMB_PASSWORD
docker compose up -d --build
Share path on the host: ./data → /data in the container.
Connect with any SMB client to //<host>/<SHARE_NAME> using SMB_USER / SMB_PASSWORD.
Without job files in config/jobs/, the container runs Samba only.
Rclone jobs
- Create config from the example (or
rclone config):
cp config/rclone.conf.example config/rclone.conf
# edit remotes / run: rclone config --config config/rclone.conf
- Add one env file per remote/path under
config/jobs/(copy an*.env.example):
cp config/jobs/photos.env.example config/jobs/photos.env
Each job uses a dedicated local directory (default /data/<job-name>) exposed through the single SMB share.
Job fields
| Field | Required | Description |
|---|---|---|
MODE |
yes | sync or mount |
REMOTE |
yes | rclone remote path, e.g. gdrive:Photos |
LOCAL |
no | local path (default /data/<filename-without-.env>) |
DIRECTION |
if MODE=sync |
pull, push, or bisync |
INTERVAL |
no | seconds between sync cycles (default 300) |
EXTRA_ARGS |
no | extra rclone flags |
Modes
| Mode | Behavior |
|---|---|
sync + pull |
rclone sync REMOTE LOCAL (cloud → disk) |
sync + push |
rclone sync LOCAL REMOTE (disk → cloud) |
sync + bisync |
rclone bisync LOCAL REMOTE with --resilient --recover; first run adds --resync |
mount |
long-running rclone mount with --allow-other and SMB uid/gid |
Bisync is an advanced rclone command: conflicts and deletions can cause data loss if misused. Read the rclone bisync docs before enabling it.
Mount needs FUSE on the host (modprobe fuse) and the compose privileges (/dev/fuse, SYS_ADMIN). Without mount jobs those privileges are unused but harmless.
Layout
config/
rclone.conf # remotes / credentials (gitignored)
jobs/
photos.env # one file per job (gitignored)
data/
photos/ # LOCAL for photos.env
notes/
Environment
| Variable | Required | Default | Description |
|---|---|---|---|
SMB_USER |
yes | — | Linux + Samba username |
SMB_PASSWORD |
one of | — | Password (prefer file in production) |
SMB_PASSWORD_FILE |
one of | — | Path to password file (e.g. Docker secret) |
SMB_UID |
no | 1000 |
UID for files on disk / rclone mount |
SMB_GID |
no | 1000 |
GID for files on disk / rclone mount |
SHARE_NAME |
no | share |
SMB share name |
SHARE_PATH |
no | /data |
Directory served by Samba |
SMB_READ_ONLY |
no | no |
yes or no |
SMB_WORKGROUP |
no | WORKGROUP |
SMB workgroup |
RCLONE_CONFIG |
no | /config/rclone.conf |
rclone config path |
RCLONE_JOBS_DIR |
no | /config/jobs |
directory of *.env job files |
RCLONE_DEBUG |
no | — | set to yes/1/true/on to enable rclone debug logs and progress during sync/mount |
If both password vars are set, SMB_PASSWORD_FILE wins.
Match SMB_UID / SMB_GID to the host user that owns ./data when you care about host-side permissions.
Security notes
- Prefer
SMB_PASSWORD_FILEoverSMB_PASSWORDin env. - Do not commit
.env,config/rclone.conf, or realconfig/jobs/*.env. - Guests are disabled; minimum protocol is SMB2.
- NetBIOS (
nmbd) is not started.
Kubernetes
Example manifests under deploy/kubernetes/:
| File | Role |
|---|---|
configmap.yaml |
Settings (smb-rclone) + job files (smb-rclone-jobs) |
secret.yaml |
smb_password + rclone.conf |
deployment.yaml |
Pod + PVC for /data, FUSE/SYS_ADMIN for mount jobs |
service.yaml |
ClusterIP on TCP 445 |
# edit secret.yaml (password + rclone.conf) and jobs in configmap.yaml
kubectl apply -f deploy/kubernetes/
SMB clients reach //smb-rclone.<namespace>.svc.cluster.local/<SHARE_NAME> (or expose the Service as NodePort / LoadBalancer if needed). Nodes that run mount jobs need the FUSE device (/dev/fuse).
Healthcheck
The image probes TCP 127.0.0.1:445 every 30s.
Build only
docker build -t docker-smb-rclone .
docker run --rm -p 445:445 \
--cap-add SYS_ADMIN --device /dev/fuse \
--security-opt apparmor:unconfined \
-e SMB_USER=smbuser \
-e SMB_PASSWORD=changeme \
-v "$(pwd)/data:/data" \
-v "$(pwd)/config:/config:ro" \
docker-smb-rclone