Database Migrations and Recovery in CasaOS: Complete Technical Guide

CasaOS implements a plug-in migration pattern via the MigrationTool interface and handles storage recovery through dedicated HTTP endpoints that rebuild rclone configurations for cloud drives.

Managing data integrity across updates and restoring cloud storage after system events are critical operations in the CasaOS ecosystem. This guide examines the exact mechanisms CasaOS uses for database schema migrations and storage recovery, referencing the actual implementation in the IceWhaleTech/CasaOS repository.

Database Migration Architecture

CasaOS treats database migrations as first-class operations through a strictly defined interface contract. The system ensures atomic updates by separating preparation, execution, and verification into distinct lifecycle phases.

The MigrationTool Interface Contract

Every migration step must implement the MigrationTool interface defined in interfaces/migrationTool.go. This contract enforces a four-phase lifecycle that prevents partial migrations:

type MigrationTool interface {
    IsMigrationNeeded() (bool, error)   // does this tool need to run?
    PreMigrate() error                  // preparations (e.g. backup)
    Migrate() error                     // actual schema/data changes
    PostMigrate() error                 // cleanup / verification
}

The boolean check in IsMigrationNeeded() allows the system to skip unnecessary work, while PreMigrate() creates safety backups before any destructive changes occur. The actual schema modifications happen in Migrate(), followed by cleanup in PostMigrate().

CLI Execution Flow

The migration driver in cmd/migration-tool/main.go discovers all compiled migration tools at build time and orchestrates their execution. The implementation iterates through the migration slice, respecting the strict phase ordering:

migrationTools := []interfaces.MigrationTool{ /* populated at build time */ }
for _, tool := range migrationTools {
    needed, err := tool.IsMigrationNeeded()
    if err != nil { … }
    if needed {
        if err := tool.PreMigrate(); err != nil { … }
        if err := tool.Migrate(); err != nil { … }
        if err := tool.PostMigrate(); err != nil { … }
    }
}

This loop guarantees transactional safety—if any phase returns an error, the process aborts immediately, preventing database corruption from partially applied migrations.

Running Migrations

Administrators interact with the migration system through the casaos migration-tool command. The CLI supports dry-run capabilities and force flags for maintenance scenarios:


# Show what would happen without actually applying changes

casaos migration-tool --dry-run

# Force a migration even if the tool thinks it's already up-to-date

casaos migration-tool -f

The tool writes detailed progress to the CasaOS logger and exits with an error code on any failure, ensuring automated scripts can detect unsuccessful migrations.

Storage Recovery Process

When cloud drives (Google Drive, Dropbox, OneDrive) become unmounted after reboots or configuration losses, CasaOS provides an automated recovery mechanism that reconstructs rclone configurations without manual intervention.

HTTP Recovery Endpoint

The recovery flow initiates at GET /api/v1/recover/:type, implemented in route/v1/recover.go. The :type path parameter accepts GoogleDrive, Dropbox, or Onedrive, routing to the appropriate driver initialization:

  • google_drive.Init
  • dropbox.Init
  • onedrive.Init

OAuth Validation and Duplicate Detection

The endpoint expects an OAuth authorization code as a query parameter. Before creating new configurations, the system checks for existing remotes using service.MyService.Storage().GetConfig(). If a matching username and type pair exists, the system reuses the existing configuration and returns a warning notification via service.MyService.Notify().SendNotify(), avoiding duplicate mount points.

Configuration Rebuilding and Remounting

For new configurations, CasaOS constructs a configuration map (dmap) containing:

  • username: Derived from the cloud account
  • client_id and client_secret: OAuth application credentials
  • token: JSON-encoded OAuth token with UTC expiry timestamp
  • mount point: /mnt/<username>

The system persists this configuration through service.MyService.Storage().CreateConfig() and executes the mount via service.MyService.Storage().MountStorage(). Each step emits status notifications (success, fail, or warn) to the frontend. The HTTP handler concludes by rendering a minimal HTML response that automatically closes the browser tab.

To trigger a Google Drive recovery manually:

GET https://<casaos-host>/api/v1/recover/GoogleDrive?code=AUTH_CODE

Key Source Files and Implementation Details

Understanding the exact file locations helps when debugging migration or recovery failures:

File Responsibility
interfaces/migrationTool.go Defines the MigrationTool interface contract
cmd/migration-tool/main.go CLI driver that discovers and executes migration tools
route/v1/recover.go HTTP handler for cloud storage recovery
service/storage.go Implements CreateConfig, GetConfig, and MountStorage methods
service/notify.go Frontend notification system for status reporting

Summary

  • CasaOS database migrations follow a strict four-phase interface (IsMigrationNeeded, PreMigrate, Migrate, PostMigrate) that ensures atomic updates and prevents partial state corruption.
  • The migration CLI (casaos migration-tool) supports dry-run and force flags for safe maintenance operations, aborting immediately on any phase failure.
  • Storage recovery reconstructs rclone configurations through the /api/v1/recover/:type endpoint, automatically handling OAuth validation and duplicate detection.
  • Both processes integrate with the notification service to provide real-time status updates to the CasaOS frontend.

Frequently Asked Questions

How do I check if CasaOS needs a database migration without applying changes?

Run casaos migration-tool --dry-run from the terminal. This executes the IsMigrationNeeded() check for all registered migration tools without invoking PreMigrate, Migrate, or PostMigrate, allowing you to preview pending changes safely.

What happens if a CasaOS migration fails halfway through?

The migration loop in cmd/migration-tool/main.go aborts immediately when any phase returns an error. Because the phases execute sequentially (PreMigrate → Migrate → PostMigrate), a failure prevents subsequent steps from running, leaving the database in its pre-migration state rather than a corrupted intermediate state.

How does CasaOS recover cloud storage after a system reboot?

The system uses the /api/v1/recover/:type endpoint to re-establish rclone configurations. When accessed with a valid OAuth code, it validates the token, checks for existing configurations via GetConfig(), and either remounts existing drives or creates new ones using CreateConfig() and MountStorage().

Can I force a migration to run even if CasaOS reports it's already up-to-date?

Yes. Append the -f or --force flag to the migration command: casaos migration-tool -f. This bypasses the IsMigrationNeeded() check and executes all phases regardless of the current state.

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 →