Skip to content

Backups

Composia automates backups through Rustic. Backup and restore tasks run on the agent, while the controller generates runtime configuration.

Architecture

Backups require a Rustic infrastructure service. The repository must declare exactly one service with infra.rustic:

rustic/composia-meta.yaml
name: rustic
nodes:
  - main
infra:
  rustic:
    compose_service: rustic
    profile: default
    data_protect_dir: /data-protect

The Rustic compose service is a normal Docker container running the rustic binary. It must have a volume that maps the agent’s {StateDir}/data-protect to the path set in data_protect_dir.

Controller configuration

controller:
  backup:
    default_schedule: "0 2 * * *"
  rustic:
    main_nodes:
      - "main"
    maintenance:
      forget_schedule: "0 1 * * Sun"
      prune_schedule: "0 3 * * Sun"
KeyDescription
backup.default_scheduleDefault cron schedule for service backups.
rustic.main_nodesNode IDs where Rustic operations run. Each must reference a configured node.
rustic.maintenance.forget_scheduleCron schedule for rustic forget.
rustic.maintenance.prune_scheduleCron schedule for rustic prune.

Service data protection

Define what to back up in composia-meta.yaml under data_protect:

data_protect:
  data:
    - name: db
      backup:
        strategy: database.pgdumpall
        service: postgres
      restore:
        strategy: database.pgimport
        service: postgres
    - name: uploads
      backup:
        strategy: files.copy_after_stop
        include:
          - ./uploads
      restore:
        strategy: files.copy
        include:
          - ./uploads

Data strategies

StrategyPurpose
files.copyBind-mount source paths into the Rustic container for read-only backup. Use for live-readable data.
files.copy_after_stopStop the compose project, bind-mount source paths, back up, then restart. Use for data that must be quiesced.
database.pgdumpallRun pg_dumpall inside the compose service. Requires service to be set.
database.pgimportRestore a PostgreSQL dump via psql. Requires service to be set.

Data action fields

KeyTypeRequired forDescription
strategystringAllBackup or restore strategy.
servicestringdatabase.*Compose service name.
include[]stringfiles.*Paths to include. Service paths (relative to service root, starts with ./ or contains /) or Docker volume names (bare name, no path separators).

Include path types

Paths can reference:

  • Service paths: files or directories inside the service directory. Bind-mounted read-only into the Rustic container via -v.
  • Named volumes: Docker volume names. Bind-mounted read-only into the Rustic container via -v (no temporary container needed).

Backup schedules

Enable scheduled backups for protected data items:

backup:
  data:
    - name: db
      provider: rustic
      enabled: true
      schedule: "0 2 * * *"
    - name: uploads
      enabled: true
      schedule: "0 3 * * Sun"
KeyTypeRequiredDescription
namestringYesMust reference a data_protect.data[].name that has a backup action.
providerstringNoBackup provider name.
enabledboolNoEnable or disable this backup.
schedulestringNoCron expression. "none" disables scheduling while keeping the entry.

When schedule is set, the controller schedules recurring backup tasks. The controller’s backup.default_schedule is used as a fallback if a service entry does not specify its own schedule.

How backup runs

A backup task executes these steps on the agent:

  1. Render: download the service bundle and the Rustic bundle from the controller. Read .composia-backup.json generated by the controller.
  2. Backup: for each data item in the runtime config:
    • files.*: create an empty staging directory under data-protect, add -v bind mounts for each include path or volume, then run docker compose run -v ... rustic backup with tags identifying the service and data item. No data is copied into the agent state directory.
    • database.pgdumpall: run docker compose exec <service> pg_dumpall, write the SQL dump to a staging file under data-protect, then run docker compose run rustic backup on the staging directory.
    • Report the result (snapshot ID) to the controller.
  3. The task finishes when all items are backed up.

Backup artifacts are identified by Rustic snapshot IDs. Tags include composia-service:<name> and composia-data:<name> for later restore and forget operations.

Restore

Trigger a restore through the web UI from the backups page or via CLI:

composia backup restore --wait --follow --timeout 30m main <backup-id>

The first argument is the target node. Use --wait --follow to block until the restore finishes and stream task logs.

The restore process:

  1. Render: download the service bundle and Rustic bundle. Read .composia-restore.json.
  2. Restore: for each item:
    • files.copy / files.copy_after_stop: clean the restore targets (must exist), create an empty staging directory under data-protect, bind-mount each target path or Docker volume into the staging tree, then run docker compose run -v ... rustic restore <snapshot_id> <staging_dir>. Restored data is written directly to the target locations — no post-restore copy step.
    • files.copy_after_stop: additionally stops the compose project before restore and restarts it after.
    • database.pgimport: run docker compose run rustic restore <snapshot_id> into a staging directory, then run docker compose exec <service> psql with the restored SQL dump.

Restore targets for files.* service paths must already exist on the agent (the target file or directory is used to determine the bind-mount semantics). Docker volume targets are cleared before restore.

Rustic maintenance

Maintenance tasks use the Rustic infrastructure service:

  • rustic_init: runs docker compose run rustic init to initialize the Rustic repository. Use once per Rustic setup.
  • rustic_forget: runs docker compose run rustic forget with tag filters. Scoped to a service, data item, or repo-wide.
  • rustic_prune: runs docker compose run rustic prune to remove unreferenced data.

Trigger maintenance from the web UI or CLI:

composia rustic init --wait --follow main
composia rustic forget --service my-app --data uploads --yes --wait --follow main
composia rustic prune --yes --wait --follow main

Use --wait --follow when you want the CLI to wait for the maintenance task and stream logs.

See also

  • Service Configuration — data protection and backup scheduling.
  • Migrate — move services between nodes with data preserved through backups.
Last updated on • Renovate Bot