Skip to content

Runbook — Restore a Docker volume from tar

Use when: a Docker volume is corrupted, accidentally pruned, or you need to recover Forgejo / Vaultwarden / MinIO data.

Warning

Vikunja #59 tracks the issue that some volume backups are empty. Always inspect the tar contents before relying on it.

Prerequisites

  • SSH access
  • The volume name (docker volume ls)
  • A backup tar in /opt/backups/volumes/<volume>_<date>.tar.gz

Steps

  1. Inspect the tar — confirm it has real data

    tar -tzf /opt/backups/volumes/<volume>_<date>.tar.gz | head -20
    du -h /opt/backups/volumes/<volume>_<date>.tar.gz
    
    If the tar is < 100 bytes or lists no real files, stop. The backup is broken — escalate to João.

  2. Stop every container using the volume

    docker ps --filter volume=<volume_name>
    docker stop <each-container>
    

  3. Snapshot the current bad state

    docker run --rm -v <volume_name>:/data -v /opt/backups/volumes:/out alpine \
      tar -czf /out/<volume>_predeath_$(date +%s).tar.gz -C /data .
    

  4. Wipe the volume

    docker volume rm <volume_name>
    docker volume create <volume_name>
    

  5. Restore from tar

    docker run --rm -v <volume_name>:/data -v /opt/backups/volumes:/in alpine \
      tar -xzf /in/<volume>_<date>.tar.gz -C /data
    

  6. Restart the containers

    docker start <each-container>
    docker logs <each-container> --tail 50
    

  7. Verify the app reads the restored data.

Common volumes

Volume Container Critical?
forgejo_forgejo-data forgejo Yes — all git repos
vaultwarden_data vaultwarden Yes — all secrets
gamine_media-storage gamine-minio Yes — uploads
infra-postgres_data infra-postgres Yes — most apps
vikunja_data vikunja Yes — task history

Rollback

If restore made things worse, repeat steps 4–6 with the _predeath_ tar from step 3.