Per-site restic backups for CloudPanel servers
  • Shell 99%
  • Dockerfile 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
René Kreijveld 8ea81641d8 Update README
2026-11-12 13:07:38 +01:00
bin clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
docs clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
etc clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
logrotate clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
scripts clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
servers clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
systemd clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
tests clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
.gitignore clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
CHANGELOG.md clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
CLAUDE.md clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
deploy.sh clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
install.sh clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
LICENSE clpbackup 1.1.0: first public release 2026-11-12 08:56:18 +01:00
README.md Update README 2026-11-12 13:07:38 +01:00

clpbackup

Per-site restic backups for CloudPanel servers, with restores that can bring back a completely deleted site.

Written by: René Kreijveld.

For every site, one snapshot contains:

  • the website files: /home/<siteuser>/, without logs, caches and tmp directories (see etc/excludes.txt)
  • the database(s): a fresh mariadb-dump of every database of the site
  • the CloudPanel configuration: the site's data from CloudPanel's SQLite database (PHP settings, vhost template, databases and users, cron jobs, FTP/SSH users, certificate, basic auth, blocked IPs/bots, Varnish settings), plus the nginx vhost, PHP-FPM pool, SSL certificate and crontab

Backups go to two independent restic repositories: a local one on the server and an offsite one (any restic backend; SFTP on a Hetzner Storage Box is used as the example in the docs).

Destination When (defaults) Retention (defaults)
Local: /var/backups/clpbackup/repo 02:00 5 daily backups
Offsite 02:00, 08:00, 14:00 and 20:00 everything from the last 7 days + 4 weekly + 12 monthly
Manual backups (both) whenever you want 30 days

Errors and warnings are mailed. Every week restic check verifies both repositories.

Features

  • Sites are discovered automatically from CloudPanel; new sites are backed up without configuration.
  • Restore without risk: by default a restore only extracts the backup to a separate directory.
  • In-place restore of files, database and/or config, after confirmation and an automatic safety backup of the current state. nginx and PHP-FPM configs are tested before they go live.
  • Deleted site? restore recreates it with clpctl (site, databases, database users), restores everything and adjusts the PHP-FPM port where needed.
  • Keeps the CloudPanel UI consistent: config restores update CloudPanel's own database too.
  • remove-site-backups cleans up all backups of a site that no longer exists.

Requirements

  • Ubuntu 24.04 with CloudPanel 2.x (tested with CloudPanel 2.5.4, MariaDB 10.11 and 11.4)
  • An offsite restic repository (SFTP, S3, B2, REST server, ...)
  • Optional: a working MTA (e.g. Postfix) for mail notifications

install.sh installs the other dependencies (sqlite3, jq, rsync, bzip2, curl) and a pinned, checksum-verified version of restic.

Quick start

git clone <this repository> clpbackup && cd clpbackup
cp etc/clpbackup.conf.example servers/server1.conf   # edit: SERVER_NAME, OFFSITE_REPO, MAIL_TO, ...
./deploy.sh root@server1                             # copies the files and runs install.sh

Then, on the server as root:

clpbackup setup-mysql      # MariaDB access (password from: clpctl db:show:master-credentials)
clpbackup init             # create repository passwords and repositories
clpbackup backup --all     # first backup
bash ~/clpbackup-src/install.sh --enable-timers

Store /etc/clpbackup/local.pass and offsite.pass in your password manager. Without them the backups cannot be restored.

Daily use:

clpbackup status                                   # last backup per site
clpbackup backup www.example.com                   # manual backup
clpbackup snapshots www.example.com --offsite      # available backups
clpbackup restore www.example.com --from local     # extract to /var/backups/clpbackup/restore/
clpbackup remove-site-backups www.old-site.com     # remove backups of a deleted site
clpbackup help

Documentation

  • docs/installation.md: installing, connecting a server, updating
  • docs/manual-backup.md: manual backups, what is in a backup, retention, removing a site
  • docs/restore.md: restoring from the local or offsite backup, all scenarios plus disaster recovery
  • PDF versions are in docs/pdf/ (rebuild with docs/build-pdf.sh)

Repository layout

bin/clpbackup                  the tool (bash)
etc/clpbackup.conf.example     config template
etc/excludes.txt               default excludes
servers/                       per-server configs (servers/<hostname -s>.conf)
systemd/                       services; install.sh generates the timers from the config
logrotate/clpbackup
install.sh                     install/update on the server (as root)
deploy.sh <ssh-host>           copy to the server and run install.sh
scripts/inventory.sh           read-only inventory of a server before installing
tests/run-docker-tests.sh      functional tests in a disposable Docker container

On the server

/usr/local/sbin/clpbackup               /usr/local/bin/restic
/etc/clpbackup/clpbackup.conf           config
/etc/clpbackup/excludes.txt             excludes; excludes.d/<domain>.txt per site
/etc/clpbackup/local.pass, offsite.pass repository passwords (also in your password manager!)
/etc/clpbackup/my.cnf                   MariaDB access
/var/backups/clpbackup/repo             local restic repository
/var/backups/clpbackup/restore/         extracted restores (clean up manually)
/var/log/clpbackup/clpbackup.log        log

Testing

tests/run-docker-tests.sh builds an Ubuntu 24.04 container with MariaDB, nginx, PHP-FPM, an SFTP server as offsite target and an emulated CloudPanel (database schema and a clpctl mock), and runs one end-to-end scenario: install, backups, excludes, retention, all restore variants including a deleted site, error handling and shellcheck. Things that cannot be tested in Docker (real clpctl, systemd timers, real mail, your offsite provider) should be verified on a test site on your server.

Disclaimer

This software comes without any warranty (see LICENSE). Backups are only as good as your last successful restore: test your restores, keep your repository passwords safe, and monitor the notifications. clpbackup is not affiliated with CloudPanel.

License

MIT — see LICENSE.