Skip to content

Implement Backup Support #315

@josecelano

Description

@josecelano

Parent Epic: #309 - Add backup support
Depends On: #310 - Research database backup strategies (completed)
Related: Roadmap Tasks 7.2-7.5

Overview

Implement backup support for Torrust Tracker deployments based on the research
findings from Issue #310. This issue consolidates the original roadmap tasks
7.2-7.5 into a single incremental implementation.

The maintenance-window hybrid approach was selected during research as the
recommended solution. This approach uses a Docker container for backup logic
(portable, tested) with minimal host-level orchestration (crontab + script).

Design Decisions

Decision Choice Rationale
Container image Pre-built on Docker Hub Generic tool, stable. No need to rebuild at deploy time.
Existing environments Not supported Deployer is deploy-only, not a manager. Must destroy and recreate.
E2E testing Unit tests + follow-up Add unit tests now; backup verification is a follow-up issue.
POC artifacts Split: docker/ + templates/ Container build files to docker/, deployment config to templates/.
Cron validation Validate format Validate 5-field cron format during config parsing.
Default template Include backup Template includes backup section by default (users can remove).
Backup scope Complete backup No partial options - database + config, all or nothing.
Backup paths Static file File locations are fixed in deployment structure, no dynamic config needed.

Goals

  • Add backup service to Docker Compose template (conditional per database)
  • Deploy backup container artifacts (Dockerfile, backup.sh) to VM
  • Install crontab for scheduled maintenance-window backups
  • Integrate backup configuration into environment creation schema
  • Update documentation

🏗️ Architecture Requirements

DDD Layers Involved:

Layer Module Path Responsibility
Domain src/domain/backup/ BackupConfig, CronSchedule types
Application src/application/command_handlers/create/config/ BackupSection DTO, validation
Application src/application/command_handlers/release/steps/ Backup deployment step
Infrastructure src/infrastructure/templating/ Template wrappers for rendering

Module Structure Requirements

  • Follow DDD layer separation (see docs/codebase-architecture.md)
  • Domain types in src/domain/backup/ (like src/domain/https/)
  • DTOs in application layer with to_domain() conversion
  • Respect dependency flow rules (dependencies flow toward domain)

Architectural Constraints

  • No business logic in presentation layer
  • Error handling follows project conventions with actionable help messages
  • Domain types are always valid (validated on construction)
  • Static templates registered in ProjectGenerator

Anti-Patterns to Avoid

  • ❌ Raw String types in domain layer (use validated value objects like CronSchedule)
  • ❌ Domain layer depending on infrastructure
  • ❌ Skipping validation in DTO → domain conversion
  • ❌ Adding Ansible when: conditionals (use Rust step logic instead)

Solution Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                           Host VM                                   │
├─────────────────────────────────────────────────────────────────────┤
│  Crontab (3:00 AM daily)                                            │
│       │                                                             │
│       ▼                                                             │
│  maintenance-backup.sh                                              │
│       │                                                             │
│       ├──► docker compose stop tracker                              │
│       │                                                             │
│       ├──► docker compose run --rm backup                           │
│       │         │                                                   │
│       │         ▼                                                   │
│       │    ┌────────────────────────────────────────┐               │
│       │    │ Backup Container                       │               │
│       │    │ - MySQL dump (if enabled)              │               │
│       │    │ - SQLite copy (if enabled)             │               │
│       │    │ - Config tar (if enabled)              │               │
│       │    │ - Compression (gzip)                   │               │
│       │    │ - Retention cleanup                    │               │
│       │    └────────────────────────────────────────┘               │
│       │                                                             │
│       └──► docker compose start tracker                             │
│                                                                     │
│  /opt/torrust/storage/backup/                                       │
│       ├── mysql/       (MySQL dumps)                                │
│       ├── sqlite/      (SQLite copies)                              │
│       └── config/      (Configuration archives)                     │
└─────────────────────────────────────────────────────────────────────┘

Implementation Plan

This plan follows a vertical slice approach where each phase delivers a complete,
testable feature.

Phase 1: Backup Container Image (Docker Hub) - Prerequisite

  • Step 1.1: Create backup container directory (docker/backup/)
  • Step 1.1b: Manual E2E Integration Test before Docker Hub publishing
  • Step 1.2: Create GitHub workflow for publishing to torrust/backup

Phase 2: Backup Service on First Run (Vertical Slice 1)

  • Step 2.1: Add backup configuration to create command (domain + application layers)
  • Step 2.2: Add backup templates and docker-compose integration
  • Step 2.3: Add backup step to Release command
  • Step 2.4: Update create template command

Phase 3: Scheduled Backups via Crontab (Vertical Slice 2)

  • Step 3.1: Add crontab templates
  • Step 3.2: Add crontab installation playbook
  • Step 3.3: Wire crontab into Configure command
  • Step 3.4: Update docker-compose to use profiles

Phase 4: Documentation and Final Testing

  • Step 4.1: Documentation
  • Step 4.2: E2E Test Updates

Backup Configuration Reference

{
  "backup": {
    "schedule": "0 3 * * *",
    "retention_days": 7
  }
}
Field Type Default Description
schedule string "0 3 * * *" Cron schedule for backups (default: 3:00 AM daily)
retention_days integer 7 Days to keep old backups before deletion

Scope Boundaries

In Scope

  • ✅ MySQL database backups (mysqldump)
  • ✅ SQLite database backups (file copy)
  • ✅ Configuration file backups (tar archive)
  • ✅ Scheduled backups via crontab
  • ✅ Backup retention (configurable days)
  • ✅ Compression (gzip)

Out of Scope

  • ❌ Restore functionality (future enhancement)
  • ❌ Remote backup destinations (S3, etc.) - user mounts volumes
  • ❌ Backup encryption (future enhancement)
  • ❌ Backup verification/testing (future enhancement)
  • ❌ Backup notifications/alerts (future enhancement)

Acceptance Criteria

  • Pre-commit checks pass: ./scripts/pre-commit.sh
  • Users can enable backup in environment configuration
  • Backup container is deployed with docker-compose stack
  • Crontab runs daily backups at configured time
  • MySQL and SQLite databases are backed up correctly
  • Configuration files are archived
  • Old backups are cleaned up per retention policy
  • Documentation covers backup usage and configuration
  • All E2E tests pass

Related Documentation


Full Specification: See docs/issues/implement-backup-support.md for complete implementation details including code examples, templates, and step-by-step tasks.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions