How to Set Up Auto-Backups with Configurable Retention in TREK

TREK includes a built-in Auto-Backup feature that creates periodic ZIP archives of your SQLite database and uploads directory, with automatic retention pruning controlled via the Admin panel or REST API.

The TREK travel management application (mauriceboe/TREK) ships with a complete server-side backup solution that requires no external cron jobs. The system handles scheduling, compression, and automatic cleanup based on a configurable retention window, all manageable from a single React-based interface or programmatically via REST endpoints.

Where Auto-Backup Logic Lives in the Codebase

The auto-backup system spans multiple layers of the NestJS/TypeScript stack. Understanding these components helps when troubleshooting or extending the functionality.

  • Backup Controller (server/src/nest/backup/backup.controller.ts): Exposes HTTP endpoints under /api/backup/*. This file handles the POST /api/backup/auto_settings request that stores your schedule configuration and the GET /api/backup/auto_settings endpoint for retrieving current settings.

  • Backup Service & Schema (shared/src/backup/backup.schema.ts): Contains the core createBackup() routine that generates ZIP files containing travel.db and the uploads/ directory. This service also implements the deleteBackup() method used during retention pruning.

  • Backup Scheduler: A cron-like interval job (search for BackupScheduler in src/nest/backup/backup.scheduler.ts) that runs once per minute to check if the current time matches your configured schedule and triggers the backup creation and subsequent pruning.

  • Client API Wrapper (client/src/api/client.ts): Provides frontend convenience functions like backup.auto_settings() that wrap the REST calls with TypeScript types.

  • Frontend UI: React components in the src/ui/backup/ directory render the Auto-Backup form, including fields for hour, day of week, day of month, and retention days.

  • Documentation (wiki/Backups.md): The definitive reference for UI field descriptions and retention behavior.

Understanding Retention and Core Concepts

Before configuring the schedule, understand how TREK handles file lifecycle and security.

Retention Policy (keepDays): After each successful backup run, the scheduler deletes all backup files (both manual and auto-generated) older than the specified number of days. The default is 7 days. Setting this value to 0 disables pruning entirely, preserving backups indefinitely.

File Naming and Storage: Auto-backups are saved as auto-backup-<timestamp>.zip while manual snapshots use backup-<timestamp>.zip. Both reside in data/backups/ relative to the server root.

Upload Limits: The server enforces a default 500 MiB size limit on backup uploads. Adjust this via the BACKUP_UPLOAD_LIMIT_MB environment variable if your uploads/ directory exceeds this limit.

Security Critical: Backups do not contain the ENCRYPTION_KEY. You must back up this key separately; restoration will fail without it.

Audit Logging: Every action is logged with specific action types: backup.auto_settings when saving the schedule, backup.create when generating a file, and backup.delete during retention cleanup.

Configuring Auto-Backups via the Web UI

The simplest way to enable scheduled backups is through the Admin panel.

  1. Navigate to Admin → Backups.

  2. In the Auto-Backup section, toggle Enabled.

  3. Configure the schedule:

    • Hour: 0-23 (UTC time of day to trigger)
    • Day of Week: 0-6 for weekly schedules (Sunday=0)
    • Day of Month: 1-28 for monthly schedules (values 29-31 are ignored to prevent end-of-month edge cases)
    • Retention – Keep last … days: Number of days to retain backups. Use 0 for "keep forever".
  4. Click Save. The client sends a POST request to /api/backup/auto_settings with your JSON payload.

Configuring Auto-Backups via the REST API

For infrastructure-as-code or remote management, use the REST API directly.

Method Endpoint Purpose
POST /api/backup/auto_settings Create or update the schedule
GET /api/backup/auto_settings Retrieve current configuration
DELETE /api/backup/auto_settings Disable auto-backup (sets enabled: false)

Node.js/Axios Example

import axios from 'axios';

const api = axios.create({ 
  baseURL: 'https://my-trek.example.com/api', 
  withCredentials: true 
});

async function enableAutoBackup() {
  await api.post('/backup/auto_settings', {
    enabled: true,
    hour: 2,          // Run at 02:00 UTC
    dayOfWeek: 0,    // Weekly on Sunday
    dayOfMonth: 1,   // Monthly on the 1st
    keepDays: 14     // Retain for 14 days
  });
  console.log('Auto-backup configured with 14-day retention');
}

enableAutoBackup().catch(console.error);

cURL Example

curl -X POST -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"enabled":true,"hour":3,"dayOfWeek":1,"dayOfMonth":1,"keepDays":30}' \
  https://my-trek.example.com/api/backup/auto_settings

How Retention Pruning Works Under the Hood

The scheduler implemented in backup.scheduler.ts executes the following logic after each backup creation:

// Simplified flow from the actual implementation
async function runAutoBackup() {
  const settings = await Settings.getAutoBackup();
  if (!isTimeToRun(settings)) return;

  // Create the archive
  const zip = await backupService.createBackup();
  await auditLog({ action: 'backup.create', resource: zip.filename });

  // Retention pruning
  if (settings.keepDays > 0) {
    const cutoff = Date.now() - settings.keepDays * 24 * 60 * 60 * 1000;
    const oldBackups = await backupService.listBackups()
      .filter(b => b.timestamp < cutoff);
    
    for (const b of oldBackups) {
      await backupService.deleteBackup(b.filename);
      await auditLog({ action: 'backup.delete', resource: b.filename });
    }
  }
}

This runs every minute via the NestJS scheduler. When the current time matches your configured hour (and optional day/week constraints), it triggers the backup, then immediately prunes any files exceeding the retention window.

Troubleshooting Common Issues

Symptom Cause Solution
"413 Payload Too Large" on upload Reverse proxy client_max_body_size is below 500 MiB Increase nginx/Caddy limit to match BACKUP_UPLOAD_LIMIT_MB
Auto-backup never executes Timezone mismatch or scheduler not running Verify server timezone and check logs for BackupScheduler startup messages
Old backups remain after retention period keepDays set to 0 or negative Set a positive integer (e.g., 30) in the auto-settings
Backup ZIP missing uploads/ content Volume permissions issue Ensure the container has write access to the ./uploads directory
Restore fails with decryption error Missing ENCRYPTION_KEY Back up the encryption key separately; it is never stored inside the ZIP

Summary

  • TREK's auto-backup is a server-side cron job that stores settings in the database and requires no external configuration.
  • The system creates ZIP archives containing travel.db and the uploads/ directory, storing them in data/backups/.
  • Retention is controlled by the keepDays parameter, which triggers automatic deletion of files older than the specified threshold after each run.
  • Configure via Admin → Backups or programmatically through POST /api/backup/auto_settings.
  • All operations generate audit logs with actions backup.create, backup.delete, and backup.auto_settings.
  • The ENCRYPTION_KEY must be backed up separately; it is excluded from all backup archives.

Frequently Asked Questions

What happens if I set keepDays to 0?

Setting keepDays to 0 disables the retention pruning entirely. The scheduler will create new backups according to your schedule but will never delete old files automatically. This is useful for compliance scenarios requiring long-term archival, but requires manual disk space monitoring.

Why isn't my auto-backup running at the scheduled time?

The scheduler checks the system time against your configured hour once per minute. If the server timezone differs from your expectation, or if the BackupScheduler service failed to initialize (check server logs for startup errors), the job will not trigger. Ensure your Docker container or host system has the correct TZ environment variable set.

Are manual backups affected by the retention policy?

Yes. The retention pruning logic in shared/src/backup/backup.schema.ts treats all files in data/backups/ equally, regardless of whether they were created manually via POST /api/backup/create or automatically. Any file older than the keepDays threshold is subject to deletion.

How do I restore from an auto-backup?

Navigate to Admin → Backups, locate the auto-backup-<timestamp>.zip file in the list, and click Restore. Alternatively, use POST /api/backup/upload_restore with the ZIP file as multipart/form-data. Ensure you have the original ENCRYPTION_KEY available, as the database cannot be decrypted without it.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →