Backup System v2 - SteamServerUI/StationeersServerUI GitHub Wiki
Stationeers Server UI - Backup System v2 Documentation
The Backup System has been completely overhauled in version 4.x, introducing "Backup System v2", or, just "Backup system" now. This new system offers improved performance, a cleaner architecture, and enhanced features. This system is designed to manage game save backups with advanced retention policies and secure storage.
Table of Contents
- Architecture Overview
- Core Components
- Backup Process
- Retention Policy
- API Reference
- Integration Guide
- Configuration
Architecture Overview
The Backup System v2 is built with a modular architecture that separates concerns into distinct components:
- BackupManager: The central component that coordinates all backup operations.
- File Watcher: Monitors backup directories for changes and triggers backup processing.
- Retention Manager: Applies backup retention policies to manage disk space.
- HTTP API: Provides RESTful endpoints for backup management.
The system handles two types of backup directories:
- Backup Directory: Where the game saves backups initially.
- Safe Backup Directory: Where copies are stored with retention policies applied.
New Stationeers Terrain System:
The Backup manager supports the new .save system since SSUI v5.5.X. It follows the same principles with backup groups generally, so all documentation for the save file trio here applies to .save files aswell
Core Components
BackupManager
The BackupManager
is the central controller for backup operations. It:
- Initializes the backup system with appropriate configuration
- Starts and manages background monitoring processes
- Coordinates backup and restore operations
- Applies retention policies through the cleanup process
type BackupManager struct {
config BackupConfig
mu sync.Mutex
watcher *fsWatcher
ctx context.Context
cancel context.CancelFunc
}
Each BackupManager instance is independent with its own configuration, making it possible to manage multiple game worlds (or games..Am I onto something?!) in the future.
File Watcher
The system uses fsnotify
to monitor for new backup files. When a new backup file is detected, it:
- Validates the file format
- Waits a configurable delay to ensure the file is fully written
- Copies the file to the safe backup directory
func (m *BackupManager) watchBackups() {
// Monitors for new backup files and processes them
}
Retention Policy
For configuration details, see the Configuration page.
The retention policy is highly configurable and follows industry best practices:
type RetentionPolicy struct {
KeepLastN int // Keep last N backups regardless of age
KeepDailyFor time.Duration // Keep daily backups for this duration
KeepWeeklyFor time.Duration // Keep weekly backups for this duration
KeepMonthlyFor time.Duration // Keep monthly backups for this duration
CleanupInterval time.Duration // How often to run cleanup
}
This provides granular control over backup retention to balance disk space with recovery options.
Backup Process
The backup process follows this workflow:
- Game creates backup files in the primary backup directory
- File watcher detects new backup files
- After a delay (default: 30 seconds), files are copied to the safe backup directory
- Periodic cleanup runs based on retention policy
- Regular backups are kept for 24 hours
- Safe backups are managed with the hierarchical retention policy
Backup File Grouping
Backup files are grouped by their index to maintain data consistency. A complete backup consists of:
world(N).xml
- World dataworld_meta(N).xml
- World metadataworld(N).bin
- Binary world data
The system ensures all three files are present when listing or restoring backups.
Retention Policy
The retention strategy is hierarchical and intelligent:
- Always keep the most recent N backups (configurable)
- Daily backups are kept for a configurable period (default: 30 days)
- Weekly backups are retained for a longer period (default: 90 days)
- Monthly backups are preserved for extended periods (default: 365 days)
This strategy provides a balance between immediate recovery needs and long-term archival.
Cleanup Algorithm
The cleanup algorithm:
- Groups backup files by index
- Sorts groups by modification time (newest first)
- Keeps the most recent N backups
- Applies the daily/weekly/monthly retention logic to older backups
- Deletes backup groups that don't meet retention criteria
API Reference
The backup system exposes RESTful API endpoints for management:
Endpoints
List Backups
GET /api/v2/backups?limit={limit}
- Description: Returns a list of available backups
- Parameters:
limit
(optional): Maximum number of backups to return
- Response: JSON array of backup groups with metadata
Restore Backup
GET /api/v2/backups/restore?index={index}
- Description: Restores a backup with the specified index
- Parameters:
index
(required): Index of the backup to restore
- Response: Success/error message
Authentication
All API endpoints are protected by JWT Cookie authentication. Clients must:
- Authenticate using
/auth/login
- Include the JWT Cookie in subsequent requests
Integration Guide
Using the Global Backup Manager
The system provides a global singleton instance for easy integration:
// Initialize the manager
backupConfig := backupsv2.GetBackupConfig()
err := backupsv2.InitGlobalBackupManager(backupConfig)
// Use the manager throughout your application
backups, err := backupsv2.GlobalBackupManager.ListBackups(10)
Creating Custom Backup Managers
This is not needed and not used the the current state of this Software. For more advanced use cases, we can create custom instances too:
config := backupsv2.BackupConfig{
WorldName: "MyWorld",
BackupDir: "./saves/MyWorld/Backup",
SafeBackupDir: "./saves/MyWorld/Safebackups",
WaitTime: 30 * time.Second,
RetentionPolicy: backupsv2.RetentionPolicy{
KeepLastN: 10,
KeepDailyFor: 30 * 24 * time.Hour,
KeepWeeklyFor: 90 * 24 * time.Hour,
KeepMonthlyFor: 365 * 24 * time.Hour,
CleanupInterval: 1 * time.Hour,
},
}
manager := backupsv2.NewBackupManager(config)
if err := manager.Initialize(); err != nil {
// Handle error
}
if err := manager.Start(); err != nil {
// Handle error
As Start calls the cleanup go routines too, be careful with "Starting" a new Manager. Initializing it is generally fine.
}
// Don't forget to shut down when done
defer manager.Shutdown()
Configuration
The default configuration can be obtained through GetBackupConfig()
:
func GetBackupConfig() BackupConfig {
backupDir := filepath.Join("./saves/" + config.WorldName + "/Backup")
safeBackupDir := filepath.Join("./saves/" + config.WorldName + "/Safebackups")
return BackupConfig{
WorldName: config.WorldName,
BackupDir: backupDir,
SafeBackupDir: safeBackupDir,
WaitTime: 30 * time.Second,
RetentionPolicy: RetentionPolicy{
KeepLastN: config.BackupKeepLastN,
KeepDailyFor: config.BackupKeepDailyFor,
KeepWeeklyFor: config.BackupKeepWeeklyFor,
KeepMonthlyFor: config.BackupKeepMonthlyFor,
CleanupInterval: config.BackupKeepMonthlyFor,
},
}
}
Key configuration options:
Option | Description | Default |
---|---|---|
WorldName | Name of the game world | From global config |
BackupDir | Primary backup directory | ./saves/{WorldName}/Backup |
SafeBackupDir | Safe storage directory | ./saves/{WorldName}/Safebackups |
WaitTime | Delay before processing new backups | 30 seconds |
KeepLastN | Number of recent backups to always keep | 10 |
KeepDailyFor | Duration to keep daily backups | 30 days |
KeepWeeklyFor | Duration to keep weekly backups | 90 days |
KeepMonthlyFor | Duration to keep monthly backups | 365 days |
CleanupInterval | Frequency of cleanup operations | 1 hour |
This documentation is intended for developers. For end-user documentation, please refer to the main wiki.