- Shell 100%
| backup | ||
| backup.service | ||
| backup.timer | ||
| install.sh | ||
| README.md | ||
Backup Automation with tar + age + systemd
A simple, secure, and automated backup solution for your self‑hosted data.
It archives files with tar, compresses with Zstandard, encrypts with age, and uploads the encrypted blob to Filen using filen-cli. The whole process is triggered daily by a systemd timer.
Overview
| Component | Description |
|---|---|
Backup script (backup) |
Archives and encrypts your data, then uploads it to Filen. |
Systemd service (backup.service) |
Runs the script as a one‑shot job. |
Systemd timer (backup.timer) |
Schedules the service to run daily with automatic catch‑up and a random delay. |
Install script (install.sh) |
Copies all files to the right places, sets permissions, and (optionally) cleans up. |
Files in this Repository
.
├── backup # The main backup script (edit this!)
├── backup.service # systemd service unit
├── backup.timer # systemd timer unit
└── install.sh # One‑step installation script
Prerequisites
- A Linux system with systemd (most modern distros).
- age – install with
apt install age,pacman -S age, or from github.com/FiloSottile/age. - filen-cli – install from the Filen CLI repository and log in once:
filen login - tar and zstd – usually pre‑installed; if not,
apt install tar zstd.
Installation
-
Clone this repository:
git clone https://codeberg.org/daesorin/backup-to-filen cd backup-to-filen -
Run the installer with root privileges:
chmod +x install.sh ./install.shThe installer will:
- Copy the backup script to
/usr/local/bin/backupand make it executable. - Copy the service and timer units to
/etc/systemd/system/. - Reload systemd.
- Ask whether to enable and start the timer now.
- Ask whether to delete the cloned folder after installation.
- Copy the backup script to
-
After installation, edit the backup script to set your own values (see below).
Configuration – Edit /usr/local/bin/backup
The script comes with placeholders – you must customise the following:
| Variable | Description |
|---|---|
AGE_PUBKEY |
Your age public key – generate one with age-keygen and copy the age1... line. |
BACKUP_SOURCES |
An array of paths you want to back up (directories or individual files). |
TEMP_FILE |
Local temporary file name (change server to your own hostname). |
filen upload ... |
The remote path on Filen (e.g., /backups/server/). |
Example:
AGE_PUBKEY='age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p'
BACKUP_SOURCES=(
"/mnt/secure"
"/etc/caddy/Caddyfile"
"/etc/containers/systemd"
)
TEMP_FILE="/tmp/myhost-${DATE}.tar.zst.age"
filen upload "$TEMP_FILE" "/myhost/backups/"
Important: The age private key (the AGE-SECRET-KEY-1... file) should never be placed on the VPS. Only the public key is used for encryption.
Usage
Manual Trigger
To test the backup manually, run:
sudo systemctl start backup.service
View Logs
sudo journalctl -u backup.service -f
Check Timer Status
sudo systemctl status backup.timer
sudo systemctl list-timers --all | grep backup
Enable/Disable Auto‑Backup
sudo systemctl enable backup.timer # start automatically on boot
sudo systemctl start backup.timer # start now
sudo systemctl disable backup.timer # stop auto‑start
sudo systemctl stop backup.timer # stop the timer
Restore Procedure
- Download the
.agefile from Filen. - Decrypt it with your age private key:
age -d -i /path/to/private-key.txt backup.age > backup.tar.zst - Extract the archive with absolute path preservation:
tar -x --zstd -P -f backup.tar.zst
The -P flag ensures that files are restored to their exact absolute paths (e.g., /etc/caddy/Caddyfile will overwrite the existing one – use with caution).
Security Notes
- The age private key is never stored on the VPS – it lives only on your trusted local machine.
- If the VPS is compromised, the attacker gets only encrypted
.agefiles and Filen upload credentials. They cannot read your data. - For additional isolation, consider using a dedicated Filen account for backups only.
Troubleshooting
| Issue | Likely cause | Solution |
|---|---|---|
age: no such file or directory |
age not installed | Install age (see Prerequisites). |
filen: command not found |
filen-cli not installed | Install filen-cli and log in once. |
tar: /mnt/secure: Cannot open: Permission denied |
Insufficient permissions | Run with sudo or adjust source paths. |
| Timer doesn't fire | Timer not enabled or started | Run systemctl enable --now backup.timer. |
AGE_PUBKEY not set in backup script |
Script not edited | Edit /usr/local/bin/backup and set your public key. |
Customisation Ideas
- Add more source paths to
BACKUP_SOURCES. - Change the
RandomizedDelaySecinbackup.timerto a fixed time. - Add pruning of old backups (e.g., keep only the last 7 days).
- Integrate a health‑check service to notify you on failure.
License
This repository is provided as-is – you are free to use and modify it for your own needs.