Backup System
Talos includes a built-in backup system that captures the full state of your installation into portable .tar.gz archives. This page covers the technical details of the backup architecture.
Backup Manager Architecture
The backup system is implemented in internal/backup with three components:
| Component | Responsibility |
|---|---|
| Manager | Orchestrates backup creation, restoration, deletion, and retention enforcement |
| Scheduler | Runs periodic backups at the configured interval using a ticker |
| Store | Persists backup metadata in the backups SQLite table |
Manager
The Manager struct holds references to the database, backup store, data directory, backup directory, retention count, and logger. It provides methods for:
CreateFullBackup-- create a new backupRestore-- restore from a backup archiveDeleteBackup-- remove a backup and its fileListBackups-- list all backup recordsStartScheduler-- begin periodic backup execution
Scheduler
The scheduler runs in a goroutine and uses a time.Ticker:
func (m *Manager) StartScheduler(ctx context.Context, interval time.Duration) {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
m.CreateFullBackup(ctx)
}
}
}The scheduler is started when TALOS_BACKUP_INTERVAL_MINUTES is greater than zero. The interval is converted from minutes to time.Duration.
Backup Creation Process
- A temporary directory is created for the SQLite snapshot.
VACUUM INTOcreates an atomic copy of the database in the temp directory.- A
.tar.gzarchive is created in the backup directory. - The database snapshot is added to the archive as
talos.db. - If a
services/directory exists under the data directory, it is walked and added to the archive. - The archive writers are flushed and closed.
- File size is recorded.
- A backup record is saved to SQLite.
- The retention policy is enforced.
VACUUM INTO
SQLite's VACUUM INTO command creates a compact, consistent copy of the database without locking the live database. This means backups can be taken while Talos is running without affecting performance or consistency.
Scheduling Engine
Configure automatic backups with environment variables:
| Variable | Default | Description |
|---|---|---|
TALOS_BACKUP_INTERVAL_MINUTES | 0 (disabled) | Backup interval in minutes |
TALOS_BACKUP_RETAIN_COUNT | 10 | Maximum number of backups to keep |
TALOS_BACKUP_DIR | data/backups | Directory for backup files |
Recommended Intervals
| Use Case | Interval | Retention |
|---|---|---|
| Development | Disabled (0) | -- |
| Production (standard) | 60 minutes | 24 (1 day) |
| Production (conservative) | 1440 minutes (daily) | 30 (1 month) |
| High-traffic | 30 minutes | 48 (1 day) |
Retention Policy
After each backup creation, the retention policy is enforced:
- All backups are listed, ordered by
created_at DESC(newest first). - If the count exceeds
TALOS_BACKUP_RETAIN_COUNT, backups beyond the limit are deleted. - Both the file on disk and the SQLite record are removed.
func (m *Manager) enforceRetentionPolicy(ctx context.Context) error {
backups, _ := m.store.ListBackups(ctx)
if len(backups) <= m.retain {
return nil
}
for _, b := range backups[m.retain:] {
m.deleteBackupFiles(b.Filename)
m.store.DeleteBackup(ctx, b.ID)
}
return nil
}Event Logging
Backup operations are logged via slog:
- Created:
backup created id=1 filename=talos-backup-20250101-120000.tar.gz size=5242880 - Deleted:
backup deleted id=1 filename=talos-backup-20250101-120000.tar.gz - Restored:
restore complete -- process must be restarted backup_id=1 - Scheduler started:
backup scheduler started interval=1h0m0s - Scheduler error:
scheduled backup failed error=... - Retention error:
retention policy enforcement failed error=...
File Format
Backup files are standard .tar.gz archives:
talos-backup-YYYYMMDD-HHMMSS.tar.gz
talos.db # SQLite VACUUM INTO snapshot
services/ # Service data volumes (if any)
<service-name>/
... # Volume contentsThe archive is created using Go's archive/tar and compress/gzip packages.
API Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /api/backups | List all backups |
POST | /api/backups | Create a new backup |
GET | /api/backups/{id}/download | Download a backup file |
POST | /api/backups/{id}/restore | Restore from a backup |
DELETE | /api/backups/{id} | Delete a backup |
Create Backup
curl -X POST http://localhost:3000/api/backups \
-H "Cookie: session=<your-session-cookie>"Response:
{
"id": 1,
"filename": "talos-backup-20250101-120000.tar.gz",
"size_bytes": 5242880,
"type": "full",
"status": "completed",
"created_at": "2025-01-01T12:00:00Z"
}List Backups
curl http://localhost:3000/api/backups \
-H "Cookie: session=<your-session-cookie>"Download Backup
curl -O http://localhost:3000/api/backups/{id}/download \
-H "Cookie: session=<your-session-cookie>"Restore Backup
curl -X POST http://localhost:3000/api/backups/{id}/restore \
-H "Cookie: session=<your-session-cookie>"WARNING
After restoring, the Talos process must be restarted. The restored database is not loaded until the process starts fresh.
Delete Backup
curl -X DELETE http://localhost:3000/api/backups/{id} \
-H "Cookie: session=<your-session-cookie>"What Gets Backed Up
| Component | Method | Notes |
|---|---|---|
| SQLite database | VACUUM INTO | Atomic, consistent snapshot |
| Service volumes | File copy | All files under data/services/ |
.env config | Included in volume copy | Contains TALOS_ENCRYPTION_KEY |
| Traefik TLS certs | Included in volume copy | Under data/traefik/data/ |
Next Steps
- Backup & Restore Guide -- hands-on backup procedures
- Architecture Overview -- system overview
- Configuration -- backup environment variables