Backup-runner Docker image intended as sidecar container in Docker Compose / Swarm stacks.
| scripts | ||
| .dockerignore | ||
| .env.example | ||
| Dockerfile | ||
| entrypoint.sh | ||
| example.docker-compose.yml | ||
| LICENSE | ||
| README.md | ||
LootGoblin (backup-runner)
A small, robust container image for running backup jobs across different environments.
This image is designed to be:
- predictable and boring (in a good way)
- easy to drop into Docker, Swarm, or Kubernetes
- flexible enough to handle common backup patterns
It focuses on data collection + transport, not long-term storage design.
Features
- File sync using
rsync - PostgreSQL dumps (
pg_dump,pg_dumpall) - MariaDB/MySQL dumps (
mysqldump) - Borg backup support (create, prune, compact)
- Simple entrypoint dispatcher
- Works with arbitrary UID/GID at runtime
Image Contents
Based on debian:bookworm-slim with:
- bash
- rsync
- postgresql-client
- mariadb-client
- borgbackup
- openssh-client
- tini
- ca-certificates
- tzdata
Project Structure
.
├── Dockerfile
├── entrypoint.sh
├── .dockerignore
└── scripts/
├── lib.sh
├── backup-rsync.sh
├── backup-postgres.sh
├── backup-mariadb.sh
├── backup-borg.sh
└── backup-all.sh
Build
docker build -t lootgoblin:latest .
Custom UID/GID:
docker build \
--build-arg BACKUP_UID=13337 \
--build-arg BACKUP_GID=13337 \
-t lootgoblin:latest .
Usage
Entrypoint Commands
backup-rsync
backup-postgres
backup-mariadb
backup-borg
backup-all
Example:
docker run --rm lootgoblin:latest backup-postgres
Environment Variables
PostgreSQL
PGHOST=
PGPORT=5432
PGUSER=
PGPASSWORD=
PGDATABASE=
PG_DUMP_ALL=false
PG_DUMP_FORMAT=custom
PG_DUMP_DIR=/staging/postgres
MariaDB / MySQL
MYSQL_HOST=
MYSQL_PORT=3306
MYSQL_USER=
MYSQL_PASSWORD=
MYSQL_DATABASE=
MYSQL_DUMP_ALL=false
MYSQL_DUMP_DIR=/staging/mariadb
rsync
RSYNC_SOURCE=
RSYNC_DEST=
RSYNC_VERBOSE=false
RSYNC_DRY_RUN=false
RSYNC_EXCLUDE_FILE=
RSYNC_RSH=
RSYNC_PATH=
RSYNC_NO_OWNER=false
RSYNC_FAKE_SUPER=false
RSYNC_PRESERVE_XATTRS=false
RSYNC_PRESERVE_ACLS=false
Borg
BORG_REPO=
BORG_PASSPHRASE=
BORG_SOURCE_PATHS=
BORG_ARCHIVE_PREFIX=backup
BORG_INIT_IF_MISSING=false
BORG_PRUNE=false
BORG_KEEP_DAILY=7
BORG_KEEP_WEEKLY=4
BORG_KEEP_MONTHLY=6
BORG_COMPACT=false
BORG_EXCLUDE_FILE=
Example (Docker Compose)
services:
backup:
image: lootgoblin:latest
command: backup-all
environment:
RUN_POSTGRES: "true"
RUN_RSYNC: "true"
RUN_BORG: "true"
PGHOST: postgres
PGUSER: backup
PGPASSWORD: secret
PGDATABASE: appdb
RSYNC_SOURCE: /data/
RSYNC_DEST: /staging/files/
BORG_REPO: /backup/repo
BORG_PASSPHRASE: secret
BORG_SOURCE_PATHS: "/staging"
volumes:
- data:/data:ro
- staging:/staging
- backup:/backup
restart: "no"
Ownership and Permissions
By default, the container runs as a non-root user.
Implications:
rsynccannot preserve ownership unless running as root- files written will be owned by the container user
Options:
- run container as root (
user: 0:0) for true ownership preservation - use
RSYNC_FAKE_SUPER=trueto store metadata in xattrs - override UID/GID at runtime to match permissions
Notes
- This image is intentionally minimal and focused
- It does not include schedulers (cron, etc.)
- It does not attempt to abstract backup logic
You are expected to orchestrate it via:
- Docker Compose
- Swarm
- Kubernetes CronJobs
- external schedulers
Philosophy
This tool acts as a courier:
- collects data (database dumps, files)
- stages it
- transports it (rsync / Borg)
It does not own the data. It does not define your backup strategy.
It simply executes it reliably.
Future Improvements
_FILEsupport for secrets- optional staging cleanup
- health/preflight checks
License
MIT (or whatever you prefer)