Systemd Deployment
This guide covers running simple-backup as a systemd service on Linux systems.
Prerequisites
- Python 3.11 or higher
- systemd-enabled Linux distribution
uvpackage manager (recommended) orpip
Installation
1. Install uv (Recommended)
curl -LsSf https://astral.sh/uv/install.sh | sh2. Clone the Repository
git clone https://github.com/reonokiy/simple-backup.git
cd simple-backup3. Install Dependencies
Using uv:
uv syncUsing pip:
pip install -r requirements.txt4. Create Environment File
Create /etc/simple-backup/backup.env with your configuration:
sudo mkdir -p /etc/simple-backup
sudo nano /etc/simple-backup/backup.envBACKUP_SOURCE_PATH=/data
BACKUP_DEST_SERVICE=s3
BACKUP_COMPRESSION=tar.zst
S3_BUCKET=my-backup-bucket
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
BACKUP_RETENTION_DAILY=7
BACKUP_RETENTION_WEEKLY=4
BACKUP_RETENTION_MONTHLY=6Secure the environment file:
sudo chmod 600 /etc/simple-backup/backup.envDeployment Methods
Recommended: One-Shot Service with Systemd Timer
This method runs backups on a schedule using systemd timers instead of a long-running process.
Create the Service File
/etc/systemd/system/simple-backup.service:
[Unit]
Description=Simple Backup Service
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/simple-backup/backup.env
ExecStart=/home/user/simple-backup/.venv/bin/python /home/user/simple-backup/main.py
User=backup
Group=backup
WorkingDirectory=/home/user/simple-backup
StandardOutput=journal
StandardError=journal
SyslogIdentifier=simple-backup
[Install]
WantedBy=multi-user.targetCreate the Timer File
/etc/systemd/system/simple-backup.timer:
[Unit]
Description=Simple Backup Timer
Requires=simple-backup.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.targetEnable and Start
sudo systemctl daemon-reload
sudo systemctl enable simple-backup.timer
sudo systemctl start simple-backup.timerCheck Status
sudo systemctl status simple-backup.timer
sudo systemctl list-timers simple-backup.timerView Logs
journalctl -u simple-backup.service -f
journalctl -u simple-backup.service --since "1 hour ago"User Setup
Create a dedicated user for running backups:
sudo useradd -r -s /bin/false -d /home/backup -m backup
sudo chown -R backup:backup /home/user/simple-backupIf backing up system files, grant read permissions:
sudo usermod -aG adm backupOr configure sudo access for specific directories:
sudo visudo -f /etc/sudoers.d/simple-backupbackup ALL=(ALL) NOPASSWD: /usr/bin/tar -czf * /var/lib/postgresql/*Storage Configuration Examples
Local Filesystem
BACKUP_DEST_SERVICE=fs
FS_ROOT=/mnt/backupsEnsure the backup user has write access:
sudo mkdir -p /mnt/backups
sudo chown backup:backup /mnt/backupsAWS S3
BACKUP_DEST_SERVICE=s3
S3_BUCKET=my-backups
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYAzure Blob Storage
BACKUP_DEST_SERVICE=azblob
AZURE_CONTAINER=backups
AZURE_ACCOUNT_NAME=myaccount
AZURE_ACCOUNT_KEY=mykeyGoogle Cloud Storage
BACKUP_DEST_SERVICE=gcs
GCS_BUCKET=my-backups
GCS_CREDENTIAL=/etc/simple-backup/gcs-credentials.jsonWebDAV
BACKUP_DEST_SERVICE=webdav
WEBDAV_ENDPOINT=https://webdav.example.com
WEBDAV_USERNAME=myuser
WEBDAV_PASSWORD=mypassMultiple Backup Jobs
Create multiple timer/service pairs with different configurations.
Create Instance-Specific Environment Files
/etc/simple-backup/database.env:
BACKUP_SOURCE_PATH=/var/lib/postgresql
BACKUP_DEST_SERVICE=s3
S3_BUCKET=database-backups
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
BACKUP_RETENTION_DAILY=7/etc/simple-backup/uploads.env:
BACKUP_SOURCE_PATH=/var/www/uploads
BACKUP_DEST_SERVICE=s3
S3_BUCKET=uploads-backups
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
BACKUP_RETENTION_WEEKLY=8Create Templated Service and Timer
/etc/systemd/system/simple-backup@.service:
[Unit]
Description=Simple Backup Service (%i)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/simple-backup/%i.env
ExecStart=/home/user/simple-backup/.venv/bin/python /home/user/simple-backup/main.py
User=backup
Group=backup
WorkingDirectory=/home/user/simple-backup
StandardOutput=journal
StandardError=journal
SyslogIdentifier=simple-backup-%i
[Install]
WantedBy=multi-user.target/etc/systemd/system/simple-backup@.timer:
[Unit]
Description=Simple Backup Timer (%i)
Requires=simple-backup@%i.service
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.targetEnable Multiple Instances
sudo systemctl daemon-reload
sudo systemctl enable simple-backup@database.timer
sudo systemctl enable simple-backup@uploads.timer
sudo systemctl start simple-backup@database.timer
sudo systemctl start simple-backup@uploads.timerView Status
systemctl list-timers simple-backup@*
systemctl status simple-backup@*
journalctl -u simple-backup@database.service -f
journalctl -u simple-backup@uploads.service -fTimer Schedule Examples
Customize the schedule by editing the OnCalendar directive in the timer file.
Daily at 2 AM:
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=trueEvery 6 hours:
[Timer]
OnCalendar=*-*-* 00/6:00:00
Persistent=trueWeekly on Sunday at 3 AM:
[Timer]
OnCalendar=Sun *-*-* 03:00:00
Persistent=trueMonthly on the 1st at 4 AM:
[Timer]
OnCalendar=*-*-01 04:00:00
Persistent=trueMultiple schedules (daily at 2 AM + weekly Sunday at 3 AM):
[Timer]
OnCalendar=*-*-* 02:00:00
OnCalendar=Sun *-*-* 03:00:00
Persistent=trueUsing shorthand (equivalent to daily):
[Timer]
OnCalendar=daily
Persistent=trueAvailable shorthands: minutely, hourly, daily, weekly, monthly, yearly
Test timer syntax:
systemd-analyze calendar "Mon *-*-* 03:00:00"
systemd-analyze calendar "daily"Monitoring and Maintenance
Check Service Health
systemctl is-active simple-backup.service
systemctl is-enabled simple-backup.service
systemctl is-failed simple-backup.serviceManual Backup Trigger
sudo systemctl start simple-backup.serviceLog Rotation
Configure journald to rotate logs:
/etc/systemd/journald.conf:
[Journal]
SystemMaxUse=1G
SystemMaxFileSize=100M
SystemMaxFiles=10Restart journald:
sudo systemctl restart systemd-journaldResource Limits
Add resource limits to service file:
[Service]
MemoryMax=512M
CPUQuota=50%
IOWeight=100Troubleshooting
Service Fails to Start
Check service status and logs:
sudo systemctl status simple-backup.service
journalctl -u simple-backup.service -n 50Permission Errors
Ensure backup user has read access to source:
sudo -u backup ls -la /path/to/sourceEnvironment Variables Not Loading
Verify environment file syntax:
cat /etc/simple-backup/backup.envReload systemd after changes:
sudo systemctl daemon-reload
sudo systemctl restart simple-backup.serviceTimer Not Triggering
Check timer status:
systemctl status simple-backup.timer
journalctl -u simple-backup.timer
systemctl list-timers --allSecurity Best Practices
Secure environment files:
bashsudo chmod 600 /etc/simple-backup/*.env sudo chown root:root /etc/simple-backup/*.envUse dedicated user with minimal privileges
Store credentials securely - consider using systemd credentials:
bashsudo systemd-creds encrypt --name=s3_secret_key - /etc/credstore/s3_secret_key.credIn service file:
iniLoadCredential=s3_secret_key:/etc/credstore/s3_secret_key.credEnable SELinux/AppArmor for additional isolation
Regular security updates:
bashcd /home/user/simple-backup git pull uv sync sudo systemctl restart simple-backup.serviceMonitor logs for suspicious activity
bashjournalctl -u simple-backup.service --since today | grep ERROR