Backup & Recovery
    Open Source

    Deploy Backrest on a VPS

    A production-ready web UI for restic — orchestrate scheduled backups, retention, notifications, and snapshot browsing across every machine you own from one self-hosted dashboard.

    At a Glance

    ProjectBackrest (web UI for restic)
    LicenseGPL v3
    Recommended PlanRamNode Cloud VPS 1–2 GB+ (4 GB+ for large repos)
    OSUbuntu 22.04 / 24.04 or Debian 12
    BackendsB2, S3, SFTP, Local, Wasabi, R2
    Estimated Setup Time30–45 minutes

    Prerequisites

    • A RamNode VPS running Ubuntu 22.04/24.04 or Debian 12
    • Root or sudo access
    • A DNS A record (e.g. backrest.example.com) pointing at the VPS
    • An offsite repository target (B2, S3, Wasabi, R2, or SFTP host)
    1

    Prepare the System

    Update and install dependencies
    apt update && apt upgrade -y
    apt install -y curl tar bzip2 ufw ca-certificates
    Create a dedicated service user
    useradd -m -s /bin/bash backrest
    Optional: add a 2 GB swap file (1–2 GB plans)
    fallocate -l 2G /swapfile
    chmod 600 /swapfile
    mkswap /swapfile
    swapon /swapfile
    echo '/swapfile none swap sw 0 0' >> /etc/fstab
    2

    Install Backrest

    Download and run the installer
    cd /tmp
    curl -sLO https://github.com/garethgeorge/backrest/releases/latest/download/backrest_Linux_x86_64.tar.gz
    mkdir backrest && tar -xzvf backrest_Linux_x86_64.tar.gz -C backrest
    cd backrest
    sudo ./install.sh
    
    systemctl stop backrest
    Hardened systemd unit
    # /etc/systemd/system/backrest.service
    [Unit]
    Description=Backrest
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=backrest
    Group=backrest
    ExecStart=/usr/local/bin/backrest
    Environment="BACKREST_PORT=127.0.0.1:9898"
    Environment="BACKREST_DATA=/home/backrest/.local/share/backrest"
    Environment="BACKREST_CONFIG=/home/backrest/.config/backrest/config.json"
    Environment="XDG_CACHE_HOME=/home/backrest/.cache"
    Restart=on-failure
    RestartSec=5
    
    NoNewPrivileges=true
    ProtectSystem=strict
    ProtectHome=false
    ReadWritePaths=/home/backrest
    PrivateTmp=true
    ProtectKernelTunables=true
    ProtectKernelModules=true
    ProtectControlGroups=true
    
    [Install]
    WantedBy=multi-user.target
    Enable and start
    mkdir -p /home/backrest/.local/share/backrest \
      /home/backrest/.config/backrest /home/backrest/.cache
    chown -R backrest:backrest /home/backrest
    
    systemctl daemon-reload
    systemctl enable --now backrest
    ss -tlnp | grep 9898   # confirm 127.0.0.1 only
    3

    First-Run Setup over an SSH Tunnel

    From your workstation, open a tunnel and complete the Backrest wizard at http://localhost:9898:

    SSH tunnel
    ssh -L 9898:127.0.0.1:9898 user@your-vps-ip
    • Set an instance ID like ramnode-backrest-01
    • Leave authentication enabled and set a strong username + password
    4

    nginx Reverse Proxy with Let's Encrypt

    Install nginx + certbot, open firewall
    apt install -y nginx certbot python3-certbot-nginx
    ufw allow OpenSSH
    ufw allow 'Nginx Full'
    ufw --force enable
    /etc/nginx/sites-available/backrest
    server {
        listen 80;
        listen [::]:80;
        server_name backrest.example.com;
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name backrest.example.com;
    
        client_max_body_size 0;
    
        location / {
            proxy_pass http://127.0.0.1:9898;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
    
            # Pass auth header explicitly (required by Backrest)
            proxy_pass_header Authorization;
            proxy_set_header Authorization $http_authorization;
    
            proxy_buffering off;
            proxy_request_buffering off;
            proxy_connect_timeout 60s;
            proxy_send_timeout 3600s;
            proxy_read_timeout 3600s;
    
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
        }
    }
    Enable and issue cert
    ln -s /etc/nginx/sites-available/backrest /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default
    nginx -t && systemctl reload nginx
    certbot --nginx -d backrest.example.com
    5

    Configure a Repository

    In the Backrest UI, click Add Repository. Pick a backend:

    • Backblaze B2: URI b2:bucket-name:/restic-repo + env vars B2_ACCOUNT_ID and B2_ACCOUNT_KEY
    • S3-compatible: URI like s3:s3.amazonaws.com/bucket/restic-repo + AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY
    • SFTP: sftp:user@host:/path/to/repo — Backrest 1.12+ generates SSH keys for you

    Important: generate a strong random repo password and store it in your password manager. Restic encrypts everything client-side — there is no recovery if you lose it.

    6

    Define a Backup Plan

    • Paths: directories to back up (overlap is cheap thanks to deduplication)
    • Schedule: cronexpr — e.g. nightly at 3:15 AM 15 3 * * *
    • Retention: keep 7 latest, 14 daily, 8 weekly, 12 monthly, 3 yearly
    Recommended excludes
    **/.cache
    **/node_modules
    **/__pycache__
    **/*.tmp
    **/lost+found
    /var/cache
    /var/tmp
    /tmp
    /proc
    /sys
    /dev
    /run

    At the repository level, schedule prune weekly (e.g. 0 5 * * 0) and check monthly with --read-data-subset=10%.

    7

    Notifications

    Under Settings → Notifications, add a Discord, Slack, Shoutrrr, Gotify, or Telegram destination. Trigger on error and success.

    Test with a deliberately failing plan (point at a non-existent path), confirm the alert fires, then fix the plan.

    8

    Hardening Passes

    • Add nginx Basic Auth in front of Backrest's own login (defense in depth)
    • Install fail2ban with the standard nginx-http-auth jail
    • Restrict the nginx location / by source IP if you only access from a few networks
    • Add /home/backrest/.config/backrest/config.json to one of your plans so the Backrest config itself is recoverable
    9

    Verify a Restore

    The only step in any backup plan that actually matters:

    1. Open the repository and pick a recent snapshot
    2. Browse to a non-trivial file, download or restore to /tmp/restore-test
    3. Compare with the live file: sha256sum or diff
    4. Repeat any time you change plans, repos, or excludes

    Troubleshooting

    • Login loops: add proxy_pass_header Authorization + proxy_set_header Authorization $http_authorization to nginx
    • Failed to acquire repo lock: use Unlock Repo after confirming nothing is running
    • fatal: bad password: the repo password is wrong — there is no recovery, verify your password manager entry
    • OOM during prune: bump VPS plan, add swap, or use --max-unused