{"id":20525897,"url":"https://github.com/deltachat/pyinfra-borgbackup","last_synced_at":"2026-04-20T02:04:15.751Z","repository":{"id":176810501,"uuid":"659602660","full_name":"deltachat/pyinfra-borgbackup","owner":"deltachat","description":"pyinfra deploy for borgbackup","archived":false,"fork":false,"pushed_at":"2024-02-26T13:43:51.000Z","size":25,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-04-13T23:18:58.371Z","etag":null,"topics":["borgbackup","pyinfra"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deltachat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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},"funding":{"custom":["https://delta.chat/en/contribute#donate-money"],"liberapay":"delta.chat","open_collective":"delta-chat"}},"created_at":"2023-06-28T07:19:16.000Z","updated_at":"2024-03-11T15:11:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"513e7da3-0772-44a1-826f-19c351ba4e32","html_url":"https://github.com/deltachat/pyinfra-borgbackup","commit_stats":{"total_commits":25,"total_committers":1,"mean_commits":25.0,"dds":0.0,"last_synced_commit":"cc98e105e734f8871ff2fe88f803c18f2d624fb6"},"previous_names":["deltachat/pyinfra-borgbackup"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deltachat%2Fpyinfra-borgbackup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deltachat%2Fpyinfra-borgbackup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deltachat%2Fpyinfra-borgbackup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deltachat%2Fpyinfra-borgbackup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deltachat","download_url":"https://codeload.github.com/deltachat/pyinfra-borgbackup/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242130240,"owners_count":20076592,"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":["borgbackup","pyinfra"],"created_at":"2024-11-15T23:10:53.541Z","updated_at":"2026-04-20T02:04:15.745Z","avatar_url":"https://github.com/deltachat.png","language":"Python","funding_links":["https://delta.chat/en/contribute#donate-money","https://liberapay.com/delta.chat","https://opencollective.com/delta-chat"],"categories":[],"sub_categories":[],"readme":"# pyinfra module to deploy our backup solution\n\nThis module deploys [borgbackup](https://www.borgbackup.org/),\nsets up a backup.sh script,\nand a cron job which executes it nightly.\n\n## Usage\n\nTo backup a host\n(called `{host}` in the rest of this guide)\nto our backup server [`hetzner-backup`](https://github.com/deltachat/sysadmin/tree/master/backup),\nyou first need to create an SSH key,\nand add the public key to the backup server's\n`/home/tech/.ssh/authorized_keys` file.\nTo do this, run the following commands\n(replace `host.name.tld` with the name of your host):\n\n```\nexport HOST=host.name.tld # enter the name of the host you want to backup here\nssh-keygen -q -t ed25519 -f /tmp/$HOST-backup -C $HOST-backup -N \"\"\nscp hetzner-backup:.ssh/authorized_keys /tmp/hetzner-backup_authorized_keys\necho 'command=\"borg serve --restrict-to-path /home/backups/'$HOST'/\",restrict' $(cat /tmp/$HOST-backup.pub) \u003e\u003e /tmp/hetzner-backup_authorized_keys\nscp /tmp/hetzner-backup_authorized_keys hetzner-backup:.ssh/authorized_keys\n```\n\nThen upload the SSH key to your server (assuming we're logging in as root)\n```\nscp /tmp/$HOST-backup $HOST/.ssh/backupkey\nscp /tmp/$HOST-backup.pub $HOST/.ssh/backupkey.pub\n```\n\nNow you need to generate a passphrase for the borg repository\nwith ```\npass generate -n delta/${HOST}/borg-passphrase\n```\nThis creates an alphanumeric passphrase for the repository.\n\nThen you can add this module to your pyinfra deploy.py script like this:\n\n```python\nfrom pyinfra import host\nfrom pyinfra.facts.files import File\nfrom pyinfra_borgbackup import deploy_borgbackup\n\nhost_name = \"host.name.tld\"\nborg_repo = f\"hetzner-backup:backups/host.name.tld\"\nborg_passphrase = \"s3cr3t\"\nborg_initialized = host.get_fact(File, \"/root/.ssh/backupkey\")\ndeploy_borgbackup(host_name, borg_passphrase, borg_repo, borg_initialized)\n```\n\nAfter it has been deployed, you should login to your host via SSH.\nThen, create the repository and create an initial backup and to directly spot possible mistakes.\n```\nsudo -i\nset -o allexport; source backup.env; set +o allexport\nborg init --encryption=repokey\n./backup.sh\n```\n\n### Use Your Own Backup Server\n\nIf you are not part of the deltachat admin team,\nyou can not use the default backup server of this module.\nIn this case, you need to upload the `/root/.ssh/config` file separately,\ne.g. in your deploy.py file.\n\nYou can take a look at our [`/root/.ssh/config`](https://github.com/deltachat/pyinfra-borgbackup/blob/main/pyinfra_borgbackup/dot_ssh/config) file\nand adjust it to your needs.\nTo upload it during your deploy.py execution,\nadd somewhere *above* the `deploy_borgbackup()` function call\nin your deploy.py file:\n\n```\nfiles.put(\n    name=\"create SSH config\",\n    src=\"path/to/the/local/ssh/config\",\n    dest=\"/root/.ssh/config\",\n    user=\"root\",\n    group=\"root\",\n    mode=\"600\",\n)\n```\n\n### Stop Services During the Backup\n\nDuring backup,\nit is recommended to halt services\nwhich write data to disk,\nso the backups don't get inconsistent.\nTo stop systemd services\nor docker containers\nduring the `borg create` step\nof the `backup.sh` script,\nyou can create a custom python script.\n\nThe `backup.sh` script will try to run `/root/backup-pre.py`,\nif the file exists;\nit calls it with the argument `stop` before `borg create`\nand with the argument `start` in the end\n(also if the backup fails for some reason).\n\nYou can use the `backup-pre.py` script from this repository\nas a template to adjust it for the specific server.\nYou need to upload the script to `/root/backup-pre.py`\nin your deploy.py script,\ne.g. directly before the `deploy_borgbackup()` call:\n\n```\nfrom pyinfra import host\nfrom pyinfra.facts.files import File\nfrom pyinfra_borgbackup import deploy_borgbackup\n\n[...]\nfiles.rsync(\n    name=\"Upload backup-pre.py\",\n    src=\"files/root/backup-pre.py\",\n    dest=\"/root/\",\n)\ndeploy_borgbackup(\"bomba\", borg_passphrase, borg_repo, borg_initialized)\n```\n\n### Enable Prometheus Monitoring For Borgbackup\n\nIf you pass a prometheus path to `deploy_borgbackup` like this:\n\n```\ndeploy_borgbackup(\n    [...]\n    prometheus_file=\"/var/lib/prometheus/node-exporter/borgbackup_finished.prom\",\n)\n```\n\nthen the backup script will track in this file when it finished successfully,\nin \"seconds since Jan 1 1970\":\n\n```\nborgbackup_last_completed 1760518220\n```\n\n#### Configure a Grafana Alert\n\nYou can use a tool like Grafana to get alerted\nwhen the backup doesn't finish for 2 days.\nFor example with the following Grafana alert rule:\n\n- 1. Enter alert rule name: `backup failed`\n- 2. Define query and alert condition\n    - A: `prometheus`, Select \"code\" in the top right, Metrics browser: `time() - borgbackup_last_completed{instance=\"bomba:9100\"}`\n    - B you can leave as it is\n    - C (Threshold): Input `A` `Is Below` `172800` (2 days in seconds)\n- 3. Set evaluation behavior\n    - Folder: `bomba`\n    - Evaluation group: `bomba`\n    - Pending period: `10m`\n- 4. You can leave as it is\n- 5. Add annotations\n    - Summary: `The last completed backup run has been over two days ago.`\n\nClick \"Save rule and exit\" to confirm.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeltachat%2Fpyinfra-borgbackup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeltachat%2Fpyinfra-borgbackup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeltachat%2Fpyinfra-borgbackup/lists"}