Refactor: Centralize configuration and improve security

- Add centralized configuration system with backup.env
- Move configuration files to proper structure (config/ directory)
- Remove hardcoded paths and make system portable
- Fix security issue: remove password exposure in gen-conf.sh
- Add comprehensive documentation (README.md, CLAUDE.md)
- Create configuration template (backup.env.sample)
- Add .gitignore to protect sensitive files
- Update all scripts to use environment variables
- Implement systemd template variable substitution

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Nicolas Duhamel 2025-06-23 21:13:11 +02:00
parent 75a1e66ed2
commit f82a913bdd
13 changed files with 399 additions and 62 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
# Configuration files with sensitive data
backup.env
config/restic.conf
# Logs
*.log
# Temporary files
*.tmp
*.bak
*~
# Cache directories
cache/
.cache/

118
CLAUDE.md Normal file
View File

@ -0,0 +1,118 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Critical Convention
**ALL scripts must be executed in an environment that has sourced the configuration:**
```bash
# Always start by sourcing configuration
source backup.env
# Then execute any script
./backup/manage list
./backup/gen-conf.sh
sudo ./backup/install-service paperless
```
This is the core architectural pattern of this codebase. Scripts do NOT auto-source configuration files.
## Common Commands
### Initial Setup
```bash
cp backup.env.sample backup.env # Copy configuration template
# Edit backup.env to match environment
source backup.env
./backup/gen-conf.sh # Generate secure Restic configuration
./backup/init-restic.sh # Initialize Restic repository
```
### Service Management
```bash
source backup.env
./backup/manage list # List all backup timers
./backup/manage status <service> # Service backup status
./backup/manage run <service> # Manual backup execution
./backup/manage logs <service> # View backup logs
sudo ./backup/install-service <service> # Install systemd timer
```
### Backup Operations
```bash
source backup.env
./backup/list-snapshots [service] # List available snapshots
./backup/restore <service> --test # Test restoration
./backup/restore <service> --production # Production restoration
```
### Configuration Testing
```bash
source backup.env
show_config # Display current configuration
validate_paths # Check directory existence
```
## Architecture
### Configuration System
- **`backup.env`**: Master configuration file at project root containing all environment variables
- **`config/restic.conf`**: Generated Restic-specific configuration (created by `gen-conf.sh`)
- **Variable substitution**: systemd templates use `${VAR}` placeholders replaced during installation
### Core Components
- **`backup/manage`**: Primary interface for all backup operations and service management
- **`backup/install-service`**: Systemd timer installer that performs variable substitution in templates
- **`backup/restore`**: Advanced restoration tool with test/production modes and safety checks
- **Templates**: `service-backup@.service` and `service-backup@.timer` are systemd unit templates
### Variable Override Pattern
Configuration uses environment variable defaults with override capability:
```bash
BACKUP_USER="${BACKUP_USER:-citadel}"
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/quantumrick}"
```
Users can customize by setting environment variables before sourcing `backup.env`.
### Systemd Integration
- Templates in `backup/` directory contain `${VARIABLE}` placeholders
- `install-service` script performs `sed` substitution to generate final systemd units
- Generated units placed in `/etc/systemd/system/` with proper permissions
### Security Model
- Restic passwords auto-generated with OpenSSL
- Configuration files have restricted permissions (600)
- Scripts validate directory existence before operations
- Restoration includes test mode for safety
## Key Files and Their Roles
### Configuration Layer
- `backup.env`: Master configuration with all variables and utility functions
- `config/restic.conf`: Generated Restic authentication and repository settings
### Operational Scripts
- `backup/manage`: Main interface (list, status, run, logs commands)
- `backup/gen-conf.sh`: Secure configuration generator
- `backup/init-restic.sh`: Repository initialization
- `backup/install-service`: Systemd timer installation with template substitution
### Templates and Restoration
- `backup/service-backup@.{service,timer}`: Systemd unit templates with variable placeholders
- `backup/restore`: Production-grade restoration with test mode and extensive validation
- `backup/list-snapshots`: Snapshot browsing utility
## Development Guidelines
When adding new scripts:
1. Add comment: `# Configuration should be sourced before running: source backup.env`
2. Use variables from `backup.env` directly (do not auto-source)
3. Follow the pattern of existing scripts for error handling and logging
4. For systemd integration, use template substitution pattern from `install-service`
When modifying configuration:
- All path variables should have environment override capability
- Maintain backward compatibility with default values
- Update both `backup.env` and this documentation if adding new variables

132
README.md Normal file
View File

@ -0,0 +1,132 @@
# QuantumRick Backup System
Système de sauvegarde automatisé basé sur Restic avec intégration systemd pour services containerisés.
## Structure du Projet
```
quantumrick/
├── backup.env # Configuration centralisée
├── config/
│ └── restic.conf # Configuration Restic (générée)
└── backup/
├── manage # Interface principale de gestion
├── gen-conf.sh # Génération de configuration Restic
├── init-restic.sh # Initialisation repository
├── install-service # Installation timers systemd
├── list-snapshots # Liste des snapshots
├── restore # Restauration
├── service-backup@.service # Template service systemd
└── service-backup@.timer # Template timer systemd
```
## Prérequis
**IMPORTANT:** Tous les scripts doivent être exécutés dans un environnement ayant sourcé la configuration :
```bash
# Toujours commencer par sourcer la configuration
source backup.env
# Puis exécuter les scripts
./backup/manage list
./backup/gen-conf.sh
./backup/init-restic.sh
```
## Installation
1. **Configuration initiale**
```bash
# Copier et adapter la configuration
cp backup.env.sample backup.env
# Éditer backup.env selon votre environnement
# Puis générer la configuration Restic
source backup.env
./backup/gen-conf.sh
```
2. **Initialisation du repository**
```bash
source backup.env
./backup/init-restic.sh
```
3. **Installation d'un service**
```bash
source backup.env
sudo ./backup/install-service <nom_service>
```
## Configuration
### Variables principales (backup.env)
- `BACKUP_USER` : Utilisateur système (défaut: citadel)
- `PROJECT_ROOT` : Racine du projet
- `SERVICES_BASE_DIR` : Répertoire des services à sauvegarder
- `BACKUP_REPOSITORY` : Chemin du repository Restic
- `DEFAULT_BACKUP_SCHEDULE` : Planning par défaut (défaut: *-*-* 03:00:00)
### Personnalisation
```bash
# Exemple pour un autre utilisateur
export BACKUP_USER="myuser"
export BACKUP_HOME="/home/myuser"
source backup.env
# Puis utiliser normalement
./backup/manage list
```
## Utilisation
### Gestion des sauvegardes
```bash
source backup.env
# Lister les timers
./backup/manage list
# Statut d'un service
./backup/manage status paperless
# Lancer une sauvegarde manuelle
./backup/manage run paperless
# Voir les logs
./backup/manage logs paperless
```
### Restauration
```bash
source backup.env
# Lister les snapshots
./backup/list-snapshots paperless
# Restaurer en mode test
./backup/restore paperless --test
# Restaurer en production
./backup/restore paperless --production
```
## Développement
Pour contribuer au projet, respectez la convention de sourcer `backup.env` dans tous vos scripts :
```bash
#!/bin/bash
# Source configuration (scripts doivent être dans backup/)
source "$(dirname "$(dirname "$0")")/backup.env"
```
## Architecture
- **Configuration centralisée** : `backup.env` contient toutes les variables
- **Scripts modulaires** : Chaque script a une responsabilité spécifique
- **Templates systemd** : Variables substituées à l'installation
- **Sécurité** : Mots de passe générés automatiquement

78
backup.env.sample Normal file
View File

@ -0,0 +1,78 @@
#!/bin/bash
# Configuration centralisée pour le système de backup quantumrick
# Copiez ce fichier vers backup.env et adaptez les valeurs selon votre environnement
# === Configuration Utilisateur ===
# Utilisateur système qui exécutera les backups
BACKUP_USER="${BACKUP_USER:-citadel}"
BACKUP_HOME="${BACKUP_HOME:-/home/$BACKUP_USER}"
# === Répertoires Principaux ===
# Racine du projet quantumrick
PROJECT_ROOT="${PROJECT_ROOT:-/home/nicolas/dev/quantumrick}"
# Répertoire où les scripts de backup sont installés
BACKUP_BASE_DIR="${BACKUP_BASE_DIR:-$BACKUP_HOME/backup}"
# Répertoire contenant les services à sauvegarder
SERVICES_BASE_DIR="${SERVICES_BASE_DIR:-$BACKUP_HOME/services}"
# Répertoire de configuration du projet
CONFIG_DIR="${CONFIG_DIR:-$PROJECT_ROOT/config}"
# === Stockage des Sauvegardes ===
# Chemin de base pour le stockage des backups
BACKUP_STORAGE_PATH="${BACKUP_STORAGE_PATH:-/mnt/data/backup}"
# Nom du repository Restic
BACKUP_REPO_NAME="${BACKUP_REPO_NAME:-quantumrick}"
# Chemin complet du repository Restic
BACKUP_REPOSITORY="${BACKUP_REPOSITORY:-$BACKUP_STORAGE_PATH/$BACKUP_REPO_NAME}"
# === Système ===
# Répertoire des services systemd
SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}"
# Répertoire des logs système
LOG_DIR="${LOG_DIR:-/var/log}"
# Répertoire temporaire
TEMP_DIR="${TEMP_DIR:-/tmp}"
# === Restic Configuration ===
# Cache Restic
RESTIC_CACHE_DIR="${RESTIC_CACHE_DIR:-$TEMP_DIR/restic-cache}"
# Fichier de configuration Restic (généré automatiquement)
RESTIC_CONFIG_FILE="${RESTIC_CONFIG_FILE:-$CONFIG_DIR/restic.conf}"
# === Templates systemd ===
# Nom des fichiers templates
SERVICE_TEMPLATE="${SERVICE_TEMPLATE:-service-backup@.service}"
TIMER_TEMPLATE="${TIMER_TEMPLATE:-service-backup@.timer}"
# === Planning par défaut ===
# Planning de sauvegarde par défaut (format systemd)
# Exemples: "*-*-* 03:00:00" (quotidien 3h), "Mon *-*-* 04:00:00" (lundi 4h)
DEFAULT_BACKUP_SCHEDULE="${DEFAULT_BACKUP_SCHEDULE:-*-*-* 03:00:00}"
# === Variables d'export pour Restic ===
export RESTIC_REPOSITORY="$BACKUP_REPOSITORY"
export RESTIC_CACHE_DIR
# Fonction utilitaire pour valider les chemins
validate_paths() {
local paths=("$BACKUP_HOME" "$SERVICES_BASE_DIR" "$(dirname "$BACKUP_STORAGE_PATH")")
for path in "${paths[@]}"; do
if [[ ! -d "$path" ]]; then
echo "WARN: Directory $path does not exist" >&2
fi
done
}
# Fonction pour afficher la configuration courante
show_config() {
echo "=== Configuration Backup ==="
echo "BACKUP_USER: $BACKUP_USER"
echo "BACKUP_HOME: $BACKUP_HOME"
echo "BACKUP_BASE_DIR: $BACKUP_BASE_DIR"
echo "SERVICES_BASE_DIR: $SERVICES_BASE_DIR"
echo "BACKUP_REPOSITORY: $BACKUP_REPOSITORY"
echo "RESTIC_CONFIG_FILE: $RESTIC_CONFIG_FILE"
echo "SYSTEMD_DIR: $SYSTEMD_DIR"
echo "LOG_DIR: $LOG_DIR"
echo "DEFAULT_BACKUP_SCHEDULE: $DEFAULT_BACKUP_SCHEDULE"
}

View File

@ -1,12 +1,13 @@
#!/bin/bash #!/bin/bash
# Script to generate Restic configuration with secure password # Script to generate Restic configuration with secure password
# Location: /home/citadel/services/paperless/generate-restic-config.sh
set -e set -e
CONFIG_FILE="/home/citadel/backup/restic.conf" # Configuration should be sourced before running: source backup.env
REPO_PATH="/mnt/data/backup/quantumrick"
CONFIG_FILE="$RESTIC_CONFIG_FILE"
REPO_PATH="$BACKUP_REPOSITORY"
echo "=== Generating Restic Configuration ===" echo "=== Generating Restic Configuration ==="
@ -28,7 +29,7 @@ RESTIC_PASSWORD=$(openssl rand -base64 32)
# Create configuration file # Create configuration file
echo "Creating configuration file..." echo "Creating configuration file..."
cat > "$CONFIG_FILE" << EOF cat > "$CONFIG_FILE" << EOF
# Restic configuration for Paperless NGX backups # Restic configuration for quantumrick backups
# Generated on $(date) # Generated on $(date)
# Repository path # Repository path
@ -38,7 +39,7 @@ export RESTIC_REPOSITORY="$REPO_PATH"
export RESTIC_PASSWORD="$RESTIC_PASSWORD" export RESTIC_PASSWORD="$RESTIC_PASSWORD"
# Cache directory (optional) # Cache directory (optional)
export RESTIC_CACHE_DIR="/tmp/restic-cache" export RESTIC_CACHE_DIR="$RESTIC_CACHE_DIR"
EOF EOF
# Set secure permissions # Set secure permissions
@ -50,5 +51,6 @@ echo ""
echo "⚠️ IMPORTANT: Save this password somewhere safe!" echo "⚠️ IMPORTANT: Save this password somewhere safe!"
echo " If you lose it, you won't be able to restore your backups!" echo " If you lose it, you won't be able to restore your backups!"
echo "" echo ""
echo "Password: $RESTIC_PASSWORD" echo "📁 Password saved in: $CONFIG_FILE"
echo " Use 'cat $CONFIG_FILE' to view the password if needed"
echo "" echo ""

View File

@ -1,12 +1,13 @@
#!/bin/bash #!/bin/bash
# Script to initialize Restic repository for Paperless NGX backups # Script to initialize Restic repository for quantumrick backups
# Location: /home/citadel/services/paperless/init-restic-repo.sh
set -e set -e
REPO_PATH="/mnt/data/backup/quantumrick" # Configuration should be sourced before running: source backup.env
CONFIG_FILE="/home/citadel/backup/restic.conf"
REPO_PATH="$BACKUP_REPOSITORY"
CONFIG_FILE="$RESTIC_CONFIG_FILE"
echo "=== Initializing Restic Repository ===" echo "=== Initializing Restic Repository ==="

View File

@ -1,11 +1,12 @@
#!/bin/bash #!/bin/bash
# Generic script to install systemd timer for any service backup # Generic script to install systemd timer for any service backup
# Location: /home/citadel/backup/install-service-timer.sh
# Usage: sudo ./install-service.sh <service_name> [schedule] # Usage: sudo ./install-service.sh <service_name> [schedule]
set -e set -e
# Configuration should be sourced before running: source backup.env
# Check arguments # Check arguments
if [ $# -lt 1 ]; then if [ $# -lt 1 ]; then
echo "Usage: $0 <service_name> [schedule]" echo "Usage: $0 <service_name> [schedule]"
@ -16,21 +17,21 @@ if [ $# -lt 1 ]; then
echo " $0 gitlab \"Mon *-*-* 04:00:00\" # Weekly on Monday at 4:00 AM" echo " $0 gitlab \"Mon *-*-* 04:00:00\" # Weekly on Monday at 4:00 AM"
echo "" echo ""
echo "Available services with backup.sh:" echo "Available services with backup.sh:"
find /home/citadel/services -name "backup.sh" -printf " %h\n" | sed 's|/home/citadel/services/||' 2>/dev/null || echo " (none found)" find "$SERVICES_BASE_DIR" -name "backup.sh" -printf " %h\n" | sed "s|$SERVICES_BASE_DIR/||" 2>/dev/null || echo " (none found)"
exit 1 exit 1
fi fi
SERVICE_NAME="$1" SERVICE_NAME="$1"
SCHEDULE="${2:-*-*-* 03:00:00}" # Default: daily at 3:00 AM SCHEDULE="${2:-$DEFAULT_BACKUP_SCHEDULE}" # Use default from config
SERVICE_DIR="/home/citadel/services/$SERVICE_NAME" SERVICE_DIR="$SERVICES_BASE_DIR/$SERVICE_NAME"
BACKUP_SCRIPT="$SERVICE_DIR/backup.sh" BACKUP_SCRIPT="$SERVICE_DIR/backup.sh"
BACKUP_DIR="/home/citadel/backup" BACKUP_DIR="$BACKUP_BASE_DIR"
# Systemd template files # Systemd template files
SERVICE_TEMPLATE="service-backup@.service" SERVICE_TEMPLATE="$SERVICE_TEMPLATE"
TIMER_TEMPLATE="service-backup@.timer" TIMER_TEMPLATE="$TIMER_TEMPLATE"
SYSTEMD_DIR="/etc/systemd/system" SYSTEMD_DIR="$SYSTEMD_DIR"
# Instance names # Instance names
SERVICE_INSTANCE="service-backup@$SERVICE_NAME.service" SERVICE_INSTANCE="service-backup@$SERVICE_NAME.service"
@ -83,21 +84,20 @@ if systemctl is-enabled --quiet "$TIMER_INSTANCE" 2>/dev/null; then
systemctl disable "$TIMER_INSTANCE" systemctl disable "$TIMER_INSTANCE"
fi fi
# Copy template files if they don't exist in systemd directory # Generate service and timer files with substituted variables
if [ ! -f "$SYSTEMD_DIR/$SERVICE_TEMPLATE" ]; then echo "Generating service file with current configuration..."
echo "Installing service template..." sed -e "s|\${BACKUP_USER}|$BACKUP_USER|g" \
cp "$BACKUP_DIR/$SERVICE_TEMPLATE" "$SYSTEMD_DIR/" -e "s|\${SERVICES_BASE_DIR}|$SERVICES_BASE_DIR|g" \
"$BACKUP_DIR/$SERVICE_TEMPLATE" > "$SYSTEMD_DIR/$SERVICE_TEMPLATE"
chmod 644 "$SYSTEMD_DIR/$SERVICE_TEMPLATE" chmod 644 "$SYSTEMD_DIR/$SERVICE_TEMPLATE"
fi
if [ ! -f "$SYSTEMD_DIR/$TIMER_TEMPLATE" ]; then echo "Generating timer file with current configuration..."
echo "Installing timer template..." sed -e "s|\${DEFAULT_BACKUP_SCHEDULE}|$DEFAULT_BACKUP_SCHEDULE|g" \
cp "$BACKUP_DIR/$TIMER_TEMPLATE" "$SYSTEMD_DIR/" "$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_TEMPLATE"
chmod 644 "$SYSTEMD_DIR/$TIMER_TEMPLATE" chmod 644 "$SYSTEMD_DIR/$TIMER_TEMPLATE"
fi
# Create custom timer with specific schedule if different from default # Create custom timer with specific schedule if different from default
if [ "$SCHEDULE" != "*-*-* 03:00:00" ]; then if [ "$SCHEDULE" != "$DEFAULT_BACKUP_SCHEDULE" ]; then
echo "Creating custom timer with schedule: $SCHEDULE" echo "Creating custom timer with schedule: $SCHEDULE"
sed "s|OnCalendar=\*-\*-\* 03:00:00|OnCalendar=$SCHEDULE|" \ sed "s|OnCalendar=\*-\*-\* 03:00:00|OnCalendar=$SCHEDULE|" \
"$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_INSTANCE" "$BACKUP_DIR/$TIMER_TEMPLATE" > "$SYSTEMD_DIR/$TIMER_INSTANCE"
@ -114,9 +114,9 @@ systemctl enable "service-backup@$SERVICE_NAME.timer"
systemctl start "service-backup@$SERVICE_NAME.timer" systemctl start "service-backup@$SERVICE_NAME.timer"
# Create log file with proper permissions # Create log file with proper permissions
LOG_FILE="/var/log/$SERVICE_NAME-backup.log" LOG_FILE="$LOG_DIR/$SERVICE_NAME-backup.log"
touch "$LOG_FILE" touch "$LOG_FILE"
chown citadel:citadel "$LOG_FILE" chown "$BACKUP_USER:$BACKUP_USER" "$LOG_FILE"
echo "" echo ""
echo "✅ Systemd timer installed successfully for $SERVICE_NAME!" echo "✅ Systemd timer installed successfully for $SERVICE_NAME!"

View File

@ -1,14 +1,15 @@
#!/bin/bash #!/bin/bash
# Script to list available snapshots from Restic repository # Script to list available snapshots from Restic repository
# Location: /home/citadel/backup/list-snapshots
# Usage: ./list-snapshots [service_name] # Usage: ./list-snapshots [service_name]
set -e set -e
# Configuration should be sourced before running: source backup.env
# Configuration # Configuration
BACKUP_DIR="/home/citadel/backup" BACKUP_DIR="$BACKUP_BASE_DIR"
CONFIG_FILE="$BACKUP_DIR/restic.conf" CONFIG_FILE="$RESTIC_CONFIG_FILE"
# Colors for output # Colors for output
BLUE='\033[0;34m' BLUE='\033[0;34m'

View File

@ -1,12 +1,13 @@
#!/bin/bash #!/bin/bash
# Script to manage backup timers for all services # Script to manage backup timers for all services
# Location: /home/citadel/backup/manage
set -e set -e
BACKUP_DIR="/home/citadel/backup" # Configuration should be sourced before running: source backup.env
SERVICES_DIR="/home/citadel/services"
BACKUP_DIR="$BACKUP_BASE_DIR"
SERVICES_DIR="$SERVICES_BASE_DIR"
show_help() { show_help() {
echo "Usage: $0 <command> [service_name]" echo "Usage: $0 <command> [service_name]"

View File

@ -1,11 +0,0 @@
# Restic configuration for Paperless NGX backups
# Generated on Mon Jun 9 11:45:41 CEST 2025
# Repository path
export RESTIC_REPOSITORY="/mnt/data/backup/quantumrick"
# Repository password
export RESTIC_PASSWORD="CHANGE-ME"
# Cache directory (optional)
export RESTIC_CACHE_DIR="/tmp/restic-cache"

View File

@ -1,15 +1,16 @@
#!/bin/bash #!/bin/bash
# Restic backup restore script # Restic backup restore script
# Location: /home/citadel/backup/restore
# Usage: ./restore <service_name> [--test|--production] # Usage: ./restore <service_name> [--test|--production]
set -euo pipefail # Strict mode: exit on error, undefined vars, pipe failures set -euo pipefail # Strict mode: exit on error, undefined vars, pipe failures
# Configuration should be sourced before running: source backup.env
# Configuration # Configuration
readonly BACKUP_DIR="/home/citadel/backup" readonly BACKUP_DIR="$BACKUP_BASE_DIR"
readonly SERVICES_DIR="/home/citadel/services" readonly SERVICES_DIR="$SERVICES_BASE_DIR"
readonly CONFIG_FILE="$BACKUP_DIR/restic.conf" readonly CONFIG_FILE="$RESTIC_CONFIG_FILE"
readonly SCRIPT_NAME=$(basename "$0") readonly SCRIPT_NAME=$(basename "$0")
readonly VERSION="2.1.0" readonly VERSION="2.1.0"
@ -269,7 +270,7 @@ create_secure_temp_dir() {
local temp_dir local temp_dir
# Use mktemp to create a secure temporary directory # Use mktemp to create a secure temporary directory
temp_dir=$(mktemp -d "/tmp/${prefix}-$(date +%Y%m%d-%H%M%S)-XXXXXX") temp_dir=$(mktemp -d "$TEMP_DIR/${prefix}-$(date +%Y%m%d-%H%M%S)-XXXXXX")
if [ ! -d "$temp_dir" ]; then if [ ! -d "$temp_dir" ]; then
error "Failed to create temporary directory" error "Failed to create temporary directory"
@ -324,7 +325,7 @@ run_custom_restore() {
log "Mode: $mode" log "Mode: $mode"
# Create restore log # Create restore log
local log_file="/tmp/restore-${service}-$(date +%Y%m%d-%H%M%S).log" local log_file="$TEMP_DIR/restore-${service}-$(date +%Y%m%d-%H%M%S).log"
# Change directory with verification # Change directory with verification
if ! cd "$service_dir"; then if ! cd "$service_dir"; then

View File

@ -5,14 +5,13 @@ Requires=docker.service
[Service] [Service]
Type=oneshot Type=oneshot
User=citadel User=${BACKUP_USER}
Group=citadel Group=${BACKUP_USER}
WorkingDirectory=/home/citadel/services/%i WorkingDirectory=${SERVICES_BASE_DIR}/%i
ExecStart=/home/citadel/services/%i/backup.sh ExecStart=${SERVICES_BASE_DIR}/%i/backup.sh
StandardOutput=journal StandardOutput=journal
StandardError=journal StandardError=journal
Environment=PATH=/usr/local/bin:/usr/bin:/bin Environment=PATH=/usr/local/bin:/usr/bin:/bin
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@ -3,8 +3,8 @@ Description=Daily Backup Timer for %i
Requires=service-backup@%i.service Requires=service-backup@%i.service
[Timer] [Timer]
# Run daily at 3:00 AM # Run daily at configured time
OnCalendar=*-*-* 03:00:00 OnCalendar=${DEFAULT_BACKUP_SCHEDULE}
# If system was down during scheduled time, run on next boot # If system was down during scheduled time, run on next boot
Persistent=true Persistent=true
# Add randomization to avoid conflicts with other services # Add randomization to avoid conflicts with other services