{"id":20622594,"url":"https://github.com/myterminal/ursa","last_synced_at":"2026-02-09T18:04:19.663Z","repository":{"id":237961671,"uuid":"795585481","full_name":"myTerminal/ursa","owner":"myTerminal","description":"My opinionated data backup and retrieval system","archived":false,"fork":false,"pushed_at":"2024-11-04T01:44:11.000Z","size":21,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T20:12:28.274Z","etag":null,"topics":["data-backup"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/myTerminal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-03T15:41:46.000Z","updated_at":"2024-11-04T01:44:14.000Z","dependencies_parsed_at":"2024-11-03T04:18:10.035Z","dependency_job_id":"8b56220d-d87a-478e-9187-fad4c1a3b9b6","html_url":"https://github.com/myTerminal/ursa","commit_stats":null,"previous_names":["myterminal/ursa-major","myterminal/ursa"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/myTerminal%2Fursa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/myTerminal%2Fursa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/myTerminal%2Fursa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/myTerminal%2Fursa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/myTerminal","download_url":"https://codeload.github.com/myTerminal/ursa/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249072610,"owners_count":21208214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["data-backup"],"created_at":"2024-11-16T12:23:40.697Z","updated_at":"2026-02-09T18:04:15.041Z","avatar_url":"https://github.com/myTerminal.png","language":"Shell","funding_links":["https://ko-fi.com/Y8Y5E5GL7"],"categories":[],"sub_categories":[],"readme":"# ursa-major\n\n[![License](https://img.shields.io/github/license/myTerminal/see-link.svg)](https://opensource.org/licenses/MIT)  \n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Y8Y5E5GL7)\n\nMy opinionated data backup and retrieval system\n\n## Purpose\n\nSince the late 1990s, I have accumulated a significant amount of personal digital data, starting from my first digital diary. Over the years, my data has migrated across various computing devices, undergone format changes, and experienced occasional data loss. My journey to find the most secure and reliable method for data storage has led me through various solutions, including external drives, cloud storage, and a network of [Syncthing](https://syncthing.net) nodes offering more than sufficient redundancy.\n\nWhile these methods have served me well, ensuring continued access to my data for an inheritor presents a challenge. Storage drives can fail, cloud services come with trust issues, and even replicating data across multiple computers is constrained by password requirements.\n\n*ursa* is designed to address these concerns by:\n\n1. **Centralizing Data:** Keeping all data in a single, cohesive location.\n2. **Enhanced Security:** Protecting data behind encrypted volumes, accessible only through independent passwords.\n3. **Redundant Copies:** Maintaining more than two redundant copies of all data to ensure reliability.\n4. **Regular Synchronization:** Continuously syncing data from its various sources to keep it up-to-date.\n5. **Error Checking and Refreshing:** Periodically refreshing and checking data for errors to ensure ongoing integrity.\n\nWith *ursa*, I could have peace of mind knowing that my data is securely managed and more accessible in case I need it available after I'm gone.\n\n## Requirements\n\n### Hardware\n\nThe system has been designed with an external storage drive in mind with the following data volumes:\n\n1. `/dev/sdb1` - Backup volume 1\n2. `/dev/sdb2` - Backup volume 2\n3. `/dev/sdb3` - Backup volume 3\n4. `/dev/sdb4` - Live volume hosting *ursa*\n\nThe above specification assumes that the external drive has been identified as `/dev/sdb` block device.\n\n### Software\n\n*ursa* is a simple set of shell scripts with the least number of external dependencies that it sets up to be able to perform its operations, which includes regular backups, updates, and eventual data retrieval by a trusted family member or inheritor.\n\n#### Suggested Volume Setup\n\nSet up partitions\n\n    cfdisk /dev/sdb\n\nPartitions:\n\n1. `/dev/sdb1` - backup partition 1\n2. `/dev/sdb2` - backup partition 2\n3. `/dev/sdb3` - backup partition 3\n4. `/dev/sdb4` - auxiliary partition\n\nFormat backup partitions with LUKS\n\n    cryptsetup -y -v luksFormat --type luks1 /dev/sdb1\n    cryptsetup -y -v luksFormat --type luks1 /dev/sdb2\n    cryptsetup -y -v luksFormat --type luks1 /dev/sdb3\n\nFormat auxiliary partition with EXT4\n\n    mkfs.ext4 /dev/sdb4\n\nOpen backup partitions to create an EXT4 underneath\n\n    cryptsetup open /dev/sdb1 vault-a\n    cryptsetup open /dev/sdb2 vault-b\n    cryptsetup open /dev/sdb3 vault-c\n    mkdir /mnt/vault-a /mnt/vault-b /mnt/vault-c\n    mount /dev/mapper/vault-a /mnt/vault-a\n    mount /dev/mapper/vault-b /mnt/vault-b\n    mount /dev/mapper/vault-c /mnt/vault-c\n    chmod 777 -R /mnt/vault-a /mnt/vault-b /mnt/vault-c\n    mkfs.ext4 /dev/mapper/vault-a\n    mkfs.ext4 /dev/mapper/vault-b\n    mkfs.ext4 /dev/mapper/vault-c\n    cryptsetup close vault-a\n    cryptsetup close vault-b\n    cryptsetup close vault-c\n\nUnmount the auxiliary partition\n\n    udisksctl unmount -b /dev/sdb4\n    udisksctl power-off -b /dev/sdb4\n\nInstall a graphical Linux distribution on the fourth volume, and deploy *ursa* on it. Follow the next section on deploying *ursa*. Preferably enable running `sudo` commands without a password.\n\n## Setup\n\nIn order to set up *ursa* on an external storage drive, clone it to a local directory, and run the following command:\n\n    make setup\n\nThis will prepare the environment with external dependencies, and internally run `./ursa-deploy`, which will prompt for a location to the fourth live volume on the target drive. Once a location is provided, and if everything goes as expected, you should be able to see the commands deployed to the specified device.\n\n## Usage\n\n*ursa* has been designed to maintain user data in a set of three identical data volumes. You may maintain your data backup in only one of the three, though keeping all three of them in sync is recommended.\n\n### Retrieving Data\n\nIf you simply need to retrieve data from the three data volumes, run:\n\n    ./ursa-retrieve\n\nYou should be presented with a file explorer window with the most recent data recorded by *ursa*.\n\n### Regular Backups\n\nIn order to backup data, you may run:\n\n    ./ursa-retrieve\n\n...which will find the most recently updated (and hence most up-to-date data volume) and unlock it for syncing files for a backup. Although, it is recommended to occasionally also sync data between all the three data-volumes and keep them in sync. This can be done using:\n\n    ./ursa-sync\n\nThis will open [meld](https://meldmerge.org) on all the three data volumes for manual sync.\n\n### Integrity Refresh (Suggested Once or Twice a Year)\n\nIt is recommended to run an integrity refresh occasionally to avoid data loss. The reason for having thee data volumes is that if during a replication cycle, a volume has been identified with issues, another one can be used for the current cycle, and the problematic volume could still be repaired from one of the two working volumes.\n\nTo start an integrity refresh cycle, simply run:\n\n    ./ursa-refresh\n\nThe scripts automatically unlocks the vaults, identify the newest and the oldest replicated volume, and the user is suggested to use the former to replicate the latter. This way, the oldest replicated volume becomes the newest for the next cycle, and effectively, all the three volumes get checked for data integrity every third replication cycle. *ursa* maintains the timestamp using an empty file named `.ursa-tag` at the root of each data volumes.\n\n### Removing the Backup Drive\n\nRemoving the backup drive can be performed using a simple command:\n\n    ./ursa-remove\n\n### Updating *ursa*\n\nIn order to update *ursa* on the backup drive, simply run:\n\n    ./ursa-update\n\n## External Dependencies\n\n- [cryptsetup](https://gitlab.com/cryptsetup/cryptsetup)\n- [udisks2](https://www.freedesktop.org/wiki/Software/udisks)\n- [meld](https://meldmerge.org)\n\n## TODO\n\n- Implement progress update during long-running processes\n- Implement \".desktop\" files for normies\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmyterminal%2Fursa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmyterminal%2Fursa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmyterminal%2Fursa/lists"}