Remember everything.
A beautiful, reliable backup orchestrator for Linux home servers. Mnemosynce (Mnemosyne + Sync) creates dated snapshots with rsync, enforces smart retention policies, syncs to remote storage, and keeps you informed via email - all managed through a clean web dashboard.
- Snapshot backups - Efficient daily/weekly/monthly/yearly snapshots using
rsync+ hard links - Simple restores - Every snapshot is a plain directory; restore a single file or everything with
cporrsync- no special tool needed - Smart retention - Automatically prunes old backups according to your policy
- Remote sync - Securely mirrors everything to a secondary location over SSH
- Web dashboard - Real-time status, history, configuration editor, and progress monitoring
- Guided setup - First-time wizard walks you through configuration, SSH keys, and scheduling
- Scheduled runs - Built-in APScheduler with flexible cron-style timing
- Email reports - Rich HTML summaries with log attachments on failures
- Multi-source - Supports local paths and remote SSH sources (
user@host:/path)
Every snapshot is a plain, browsable directory. There is no proprietary format, no import command, no restore wizard. When you need a file back, you already know how:
# Restore a single file
cp /mnt/backup/local/Documents/2026-04-19/report.pdf ~/Documents/report.pdf
# Restore an entire snapshot
rsync -az /mnt/backup/local/Documents/2026-04-19/ /home/user/Documents/Unchanged files are stored as hard links across snapshots, so each dated folder looks complete while taking only a fraction of the space. Deleting one snapshot never affects the others.
Full user and developer documentation - including a full restore guide - is available at the project's GitHub Pages site. See docs-site/ for the source, built with Zensical.
docker run -d \
--name mnemosynce \
-v ./data:/data \
-v /mnt/backup:/mnt/backup \
-p 5000:5000 \
-e SECRET_KEY=change-me \
-e ADMIN_PASSWORD=change-me \
-e GMAIL_ADDRESS=you@gmail.com \
-e GMAIL_PASSWORD=your-app-password \
ghcr.io/mark-me/mnemosynce:latestThen open http://your-server:5000 and follow the setup wizard.
Note
SECRET_KEY and ADMIN_PASSWORD must be changed from the defaults.
The container will refuse to start in production if they are left as placeholders.
Important
GMAIL_PASSWORD must be a Gmail app password, not your regular Google account password. See the Gmail app password setup guide for instructions.
Tip
Before running your first backup, go to Settings → Connections and use the Trust host key panel for each remote host. SSH refuses to connect non-interactively to unknown hosts, so this step is required before connection tests or backup runs will succeed.
git clone https://github.com/mark-me/mnemosynce.git
cd mnemosynce
uv sync
cp .env.example .env # fill in your valuesStart the development server:
uv run flask --app src/web/app:create_app run --host 0.0.0.0 --port 5000Or use Gunicorn for production:
uv run gunicorn \
--bind 0.0.0.0:5000 \
--workers 2 \
--timeout 120 \
"web.app:create_app()"All persistent data lives in the /data volume (or dev-data/ in development):
| Path | Purpose |
|---|---|
backup_config.yml |
Backup task definitions |
log.db |
Run history for the dashboard |
ssh/ |
SSH keypairs, ssh_config, and known_hosts - all managed via the web UI |
Example backup_config.yml:
dir_backup_local: /mnt/backup/local
dir_backup_remote: user@backup-host:/mnt/backup/remote
email_sender: you@gmail.com
email_report: you@example.com
tasks:
- name: Documents
dir_source: /home/user/Documents
excludes:
- "*.tmp"
- "cache/"
- name: DesktopHome
dir_source: user@desktop:/home/user # remote source over SSH
excludes:
- Downloads/*
- .cacheInstall dev dependencies:
uv sync --extra devStart the dev server (login is bypassed in development mode):
uv run flask --app src/web/app:create_app run --debugRun the test suite:
uv run pytest -m "not functional" # fast, no real scripts needed
uv run pytest --cov=src --cov-report=term-missing -m "not functional"mnemosynce/
├── src/
│ ├── backup_server/ # Core backup engine - no Flask dependency
│ │ ├── backup_task.py # Orchestrates one task: backup → retention → sync
│ │ ├── config_file.py # Reads and validates backup_config.yml
│ │ ├── database.py # SQLite run log
│ │ ├── email_report.py # Composes and sends the HTML status email
│ │ ├── main.py # CLI entry point
│ │ ├── backup.sh # rsync snapshot script
│ │ ├── delete_old_backups.sh # Retention policy script
│ │ └── sync_backup_to_remote.sh # Remote sync script
│ ├── config/
│ │ └── config.py # Flask config classes (Dev / Test / Production)
│ └── web/
│ ├── app.py # Flask application factory
│ ├── scheduler.py # APScheduler singleton + live log bridging
│ ├── setup_state.py # Session-backed setup readiness checks
│ └── routes/ # One blueprint per feature area
├── docs-site/ # Zensical documentation source
│ ├── zensical.toml
│ └── docs/
│ ├── user/ # User guide
│ └── developer/ # Developer guide
├── tests/ # pytest suite (88 tests, no real I/O)
├── docker/Dockerfile
└── pyproject.toml
Mnemosynce is built on great open source work. See ACKNOWLEDGEMENTS.md for the full list of libraries and tools that make it possible.
MIT © 2026 Mark Zwart
