Peter van Arkel 6d9ddc4457 refactor: stop using legacy JSON for runtime config
Build runtime pobsync configuration exclusively from structured SQL
fields, leaving legacy JSON only for import and audit context. Add
SQL-first management commands for global and host configuration and
cover them with tests.
2026-05-19 05:08:37 +02:00

pobsync

pobsync is a pull-based backup tool that runs on a central backup server and pulls data from remote servers via rsync over SSH.

Key points:

  • All backup data lives on the backup server.
  • Snapshots are rsync-based and use hardlinking (--link-dest) for space efficiency.
  • Designed for scheduled runs (cron) and manual runs.
  • Minimal external dependencies (currently only PyYAML).

Requirements

On the backup server:

  • Python 3
  • rsync
  • ssh
  • SSH key-based access from the backup server to remotes

Canonical installation (no venv, repo used only for deployment)

This project uses a simple and explicit deployment model:

  • The git clone is only used as a deployment input (and later for updates).
  • Runtime code is deployed into /opt/pobsync/lib.
  • The canonical entrypoint is /opt/pobsync/bin/pobsync.

Install

cd pobsync
sudo ./scripts/deploy --prefix /opt/pobsync

pobsync install --backup-root /mnt/backups/pobsync (install default configurations)
pobsync doctor (check if the installation was done correctly)

Update

cd /path/to/pobsync
git pull

sudo ./scripts/deploy --prefix /opt/pobsync
sudo /opt/pobsync/bin/pobsync doctor

Configuration

Global configuration is stored at:

  • /opt/pobsync/config/global.yaml

Per-host configuration files are stored at:

  • /opt/pobsync/config/hosts/.yaml

Some useful commands to get you started

Create a new host configuration:

pobsync init-host <host>

List configured remotes:

pobsync list-remotes

Inspect the effective configuration for a host:

pobsync show-config <host>

Running backups

Run a scheduled backup for a host:

pobsync run-scheduled <host>

Optionally apply retention pruning after the run:

pobsync run-scheduled <host> --prune

Scheduling (cron)

Create a cron schedule (writes into /etc/cron.d/pobsync by default):

pobsync schedule create <host> --daily 02:15 --prune

List existing schedules:

pobsync schedule list

Remove a schedule:

pobsync schedule remove <host>

Cron output is redirected to:

  • /var/log/pobsync/.cron.log

Development (optional)

For development purposes you can still use an editable install, this is why pyproject.toml still exists. On systems with an externally managed Python installation, create a virtualenv first.

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -e .
pobsync --help

For production use, always use the canonical entrypoint:

/opt/pobsync/bin/pobsync

Django backend (early refactor layer)

The Django backend is becoming the management layer and source of truth for pobsync. Structured SQL fields store backup, SSH, rsync, retention, schedule, run, and snapshot state; legacy JSON/YAML remains only as an import/export compatibility path while the engine is being refactored.

Local SQLite development

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -e .
mkdir -p var
python3 manage.py migrate
python3 manage.py createsuperuser
python3 manage.py runserver

The admin is available at:

Import existing YAML configs into the database:

python3 manage.py import_pobsync_configs --prefix /opt/pobsync

Create SQL-backed configuration directly:

python3 manage.py configure_pobsync_global --backup-root /mnt/backups/pobsync
python3 manage.py configure_pobsync_host <host> --address <host-or-ip>

Run a backup through Django while still using the existing pobsync engine:

python3 manage.py run_pobsync_backup <host> --prefix /opt/pobsync --prune

The Django backup command reads backup and retention config from SQL directly. Runtime YAML export is kept as a compatibility tool for older CLI flows during the transition.

Export database configs to runtime YAML for legacy CLI compatibility:

python3 manage.py export_pobsync_configs --prefix /opt/pobsync

Run due schedules from the database:

python3 manage.py run_pobsync_scheduler --loop --interval 60

Docker with SQLite

docker compose up --build web

This starts Django on:

The container persists /opt/pobsync and the SQLite database in Docker volumes.

Run the Django scheduler alongside the web admin:

docker compose up --build web scheduler

Docker with MariaDB

docker compose --profile mariadb up --build web-mariadb

With the scheduler:

docker compose --profile mariadb up --build web-mariadb scheduler-mariadb

The MariaDB profile is optional. SQLite remains the default because it is enough for a single backup server and keeps deployment simple.

Refactor direction

Recommended next steps:

  • Remove remaining legacy YAML-first commands after SQL-first setup covers all workflows.
  • Record more engine-side run details into BackupRun and SnapshotRecord.
  • Treat SQL as the source of truth and export YAML only as a compatibility layer for the current engine.
  • Run schedules from Django/Docker instead of writing host cron files.
  • Add a snapshot discovery command that syncs existing snapshot metadata into SnapshotRecord.
  • Add tests around retention, scheduling, and config merge before deeper internal reshaping.
Description
Rsync-based backup solution.
Readme 3.3 MiB
pobsync 1.2.0 Latest
2026-05-28 22:19:23 +02:00
Languages
Python 77.9%
HTML 19.6%
Shell 2.4%
Dockerfile 0.1%