Super Java Host
  1. Home
  2. Guides
  3. Back up with restic

Back up a Java VPS with restic

Encrypted, deduplicated daily backups of your application files and database to another location, with a retention policy and a tested restore.

What to back up

  • Your application files and configuration: /opt/app, /etc/app.env, the Nginx site file, systemd units, uploaded files.
  • The database, as a dump (not the live data files).
  • Not the operating system, the JDK or downloaded application servers. Those are easy to reinstall.

A backup on the same disk is not a backup. Send it to a different provider.

1. Install restic and set up a repository

sudo apt install -y restic
sudo mkdir -p /etc/restic /var/backups/db
sudo tee /etc/restic/env >/dev/null <<'EOF'
export RESTIC_REPOSITORY="s3:https://s3.example.com/my-bucket/server1"
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
export RESTIC_PASSWORD_FILE="/etc/restic/password"
EOF
openssl rand -base64 32 | sudo tee /etc/restic/password >/dev/null
sudo chmod 600 /etc/restic/env /etc/restic/password
sudo bash -c '. /etc/restic/env; restic init'

For SFTP use sftp:user@host:/backups/server1 with an SSH key. Store the password somewhere other than this server: without it the backups cannot be read.

2. The backup script

sudo tee /usr/local/bin/backup-run >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
. /etc/restic/env

# database dump (use the one you have)
sudo -u postgres pg_dump -Fc appdb > /var/backups/db/appdb.dump
# mysqldump --single-transaction appdb | gzip > /var/backups/db/appdb.sql.gz

restic backup /opt/app /etc/app.env /etc/nginx/sites-available /etc/systemd/system /var/backups/db
restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6
EOF
sudo chmod 700 /usr/local/bin/backup-run
sudo /usr/local/bin/backup-run

Database dumps are consistent. Copying a running database's files is not.

3. Run it every night

sudo tee /etc/systemd/system/backup.service >/dev/null <<'EOF'
[Unit]
Description=Nightly backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-run
EOF
sudo tee /etc/systemd/system/backup.timer >/dev/null <<'EOF'
[Unit]
Description=Nightly backup

[Timer]
OnCalendar=*-*-* 03:30
RandomizedDelaySec=15m
Persistent=true

[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers backup.timer

Check a result: journalctl -u backup.service -n 20. Add a failure alert, see monitoring.

4. Test the restore

A backup you have not restored is a guess.

sudo bash -c '. /etc/restic/env; restic snapshots'
sudo bash -c '. /etc/restic/env; restic restore latest --target /tmp/restore-test'
sudo -u postgres pg_restore --list /tmp/restore-test/var/backups/db/appdb.dump | head

Do this once now and then every few months. Delete /tmp/restore-test afterwards.

Our managed plans include daily offsite backups with the same retention (7 daily, 4 weekly, 6 monthly).

Last updated October 29, 2026.

Your own Java server, billed monthly

Plans from €15.30 a month. Set up for you, or run for you.