{"id":40392627,"url":"https://github.com/perfacilis/backup","last_synced_at":"2026-01-20T12:38:03.508Z","repository":{"id":37075050,"uuid":"467271987","full_name":"perfacilis/backup","owner":"perfacilis","description":"RSYNC incremental backup script","archived":false,"fork":false,"pushed_at":"2025-10-02T11:57:13.000Z","size":70,"stargazers_count":5,"open_issues_count":1,"forks_count":4,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-02T13:38:41.010Z","etag":null,"topics":["incremental-backups","rsync-backup"],"latest_commit_sha":null,"homepage":"https://www.perfacilis.com/blog/systeembeheer/linux/rsync-daily-weekly-monthly-incremental-back-ups.html","language":"Shell","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/perfacilis.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,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-07T21:56:28.000Z","updated_at":"2025-10-02T11:57:16.000Z","dependencies_parsed_at":"2024-03-06T18:56:09.968Z","dependency_job_id":"bafa2d8b-df99-4e80-ad8a-4a2f6c619b2e","html_url":"https://github.com/perfacilis/backup","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/perfacilis/backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perfacilis%2Fbackup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perfacilis%2Fbackup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perfacilis%2Fbackup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perfacilis%2Fbackup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/perfacilis","download_url":"https://codeload.github.com/perfacilis/backup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/perfacilis%2Fbackup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28603392,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T12:01:53.233Z","status":"ssl_error","status_checked_at":"2026-01-20T12:01:46.545Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["incremental-backups","rsync-backup"],"created_at":"2026-01-20T12:38:02.872Z","updated_at":"2026-01-20T12:38:03.501Z","avatar_url":"https://github.com/perfacilis.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RSYNC incremental backup script\n\nRsync backup script free to use:\n- Linux implementation in bash\n    - See: https://www.perfacilis.com/blog/systeembeheer/linux/rsync-daily-weekly-monthly-incremental-back-ups.html\n- Windows implementation in Powershell\n    - See: https://www.perfacilis.com/blog/systeembeheer/windows/windows-incremental-back-up-using-rsync-and-powershell.html\n\nI'm using this script to back-up all my Windows \u0026 Linux workstations and \nservers without trouble, nonetheless this script comes with no warranty\nwhatsoever.\n\n**Please check the integrity of your back-ups periodically!**\n\n\n## We're hoping for your feedback...\n\n![GIF I like it a lot](https://i.imgflip.com/lo6p.gif)\n\nTried this script for a bit? Like it? Or hate it?\n\nIt would help my business like a lot if you would take just 60 seconds out of \nyour time and tell us what you think:\nhttp://g.page/perfacilis/review\n\n\n## Installation\n\n### Installation on Linux\n\nSimply download the latest version, change the `readonly` variables in the first \nfew lines of the script and install it as an (hourly) cronjob. For example:\n\n```bash\n# Never copy-pasta stuff from the webz into your terminal, always check first!\nwget -qO- https://raw.githubusercontent.com/perfacilis/backup/master/backup | sudo tee /etc/cron.hourly/backup\nsudo chmod 700 /etc/cron.hourly/backup\n\n# Change BACKUP_LOCAL_DIR, BACKUP_DIRS, etc\nnano /etc/cron.hourly/backup\n\n# Optionally run it manually\nsudo /etc/cron.hourly/backup\n\n# Or watch your syslog\ntail -f /var/log/syslog | grep --color --line-buffered \"backup:\"\n```\n\n### Installation on Windows\n\nFirst, you'll need a Windows implementation of Rsync, for example:\n    https://itefix.net/cwrsync-client\nDownload the zip and extract so you get `C:\\backup\\rsync\\bin\\rsync.exe`\n\nThen, like the Linux installation, download the latest version, change the \nvariables in the first few lines and install a Scheduled Task. For example:\n\n```shell\nNew-Item -Path \"C:/backup\" -ItemType Directory\nSet-Location C:/backup\n\n# Retrieve cwrsync (cygwin rsync), run commented out TLS-fix for older pwsh versions\n#[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\nInvoke-WebRequest -Uri https://itefix.net/dl/free-software/cwrsync_6.2.8_x64_free.zip -OutFile rsync.zip\nExpand-Archive rsync.zip\nRemove-Item rsync.zip\n\n# Download the file, don't forget to change the settings!\nInvoke-WebRequest -Uri https://raw.githubusercontent.com/perfacilis/backup/master/backup.bs1 -OutFile backup.ps1\n\n# Create an hourly scheduled task, powershell flavour\n# See: Task Scheduler » Microsoft » Windows » Powershell » ScheduledJobs\n$trigger = New-JobTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1) -RepeatIndefinitely\n$callback = {Start-Process \"powershell.exe\" -ArgumentList \"C:\\backup\\backup.ps1\" -Wait -NoNewWindow}\nRegister-ScheduledJob -Name \"backup.ps1\" -Trigger $trigger -MaxResultCount 99 -ScriptBlock $callback\n```\n\n\n## Basic usage\n\n### Rsync profile\n\nDefault usage, backup to a server with an Rsync profile:\n\n```bash\nreadonly RSYNC_TARGET=\"username@backup.perfacilis.com::profile\"\nreadonly RSYNC_DEFAULTS=\"-trlqpz4 --delete --delete-excluded --prune-empty-dirs\"\nreadonly RSYNC_EXCLUDE=(tmp/ temp/)\nreadonly RSYNC_SECRET='RSYNCSECRETHERE'\n```\n\n### Local backup\n\nIf you want to backup to a USB disk for example:\n\n```bash\nreadonly RSYNC_TARGET=\"/media/user/backup_drive\"\nreadonly RSYNC_DEFAULTS=\"-trlqpz4 --delete --delete-excluded --prune-empty-dirs\"\nreadonly RSYNC_EXCLUDE=(tmp/ temp/)\nreadonly RSYNC_SECRET=''\n```\n\n### Rsync over ssh\n\nRsync using ssh to communicate instead of rsync profiles.\nYou'll have to set up SSH Public Key authentication:\n\n```bash\nreadonly RSYNC_TARGET=\"username@backup.perfacilis.com:/path/on/ssh/server\"\nreadonly RSYNC_DEFAULTS=\"-trlqpz4 --delete --delete-excluded --prune-empty-dirs -e \"'\"ssh -p 2222\"'\"\"\nreadonly RSYNC_EXCLUDE=(tmp/ temp/)\nreadonly RSYNC_SECRET=''\n```\n\n\n## Databases\n\nWhen `$DB_LIST` is not empty, the script tries to backup all listed names into \na GZIP file. Therefore, leave empty if you don't want to backup databases. For\nevery database, `$DB_DUMP` is run, so change this according to your database \nsystem.\n\nSee some examples below.\n\n### MySQL examples\nFor **MariaDB** use `mariadb` instead of `mysql` and `mariadb-dump` instead of\n`mysqldump`.\n\n```bash\nreadonly DB_LIST=\"database1 database2\"\nreadonly DB_LIST=\"$(mysql -Bse 'SHOW DATABASES')\"\n\nreadonly DB_DUMP=\"mysqldump --defaults-file=/etc/mysql/debian.cnf -E -R --max-allowed-packet=512MB -q --single-transaction -Q --skip-comments\"\nreadonly DB_DUMP=\"mysqldump --defaults-file=/etc/mysql/debian.cnf --ssl-mode=VERIFY_CA --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -E -R --max-allowed-packet=512MB -q --single-transaction -Q --skip-comments\"\nreadonly DB_DUMP=\"mysqldump --defaults-extra-file=/root/.mysqldump -E -R --max-allowed-packet=512MB -q --single-transaction -Q --skip-comments\"\nreadonly DB_DUMP=\"mysqldump --username=PLSDONT --password=PLSDONT -E -R --max-allowed-packet=512MB -q --single-transaction -Q --skip-comments\"\n```\n\nThe script runs as root, later versions of MySQL and MariaDB don't require any\ncredentials, but if you want to use a specific user, you can create a\ndefaults-file:\n```txt /root/.mysqldump\n[mysql]\nuser=USERNAME\npassword=PASSWORD\n\n[mysqldump]\nuser=USERNAME\npassword=PASSWORD\n```\n\n### MySQL per table backup\nWhen `$DB_TABLE_LIST` is not empty, the script creates a GZIP file per TABLE\ninstead of per DATABASE. Therefore, leave it empty if you want backups per\nDATABASE or if your DBMS doesn't support this.\n\nThe command arguments needs to be defined as an array to support quotes:\n```bash\nreadonly DB_TABLE_LIST=(mariadb -Bse \"SELECT TABLE_NAME, Update_time FROM information_schema.tables WHERE TABLE_SCHEMA = '%DB%' ORDER BY TABLE_NAME;\")\n```\n\n### PostgreSQL examples\n\n```bash\nreadonly DB_LIST=\"$(psql -h 127.0.0.1 -U restore --no-password -l -t | grep '^ \\w' | grep -v 'template' | awk '{print $1}')\"\nreadonly DB_DUMP=\"pg_dump -h 127.0.0.1 -U restore --no-password -d\"\n```\n\nIt's recommended to create a user to allow databases to be dumped without user\ninteraction:\n```bash\nsudo -u postgres psql -c \"CREATE USER restore SUPERUSER PASSWORD 'secret';\"\nsudo -u postgres psql -c \"GRANT pg_read_all_data TO restore;\necho '*:*:*:restore:SECRETPASSWORD' | sudo tee /root/.pgpass\nsudo chmod 600 /root/.pgpass\n```\n\n### Database encryption\nPoint `$DB_ENCRYPTION_KEY` to a public key file to database dump files. This\nkey file must be a PEM file, for example:\n```bash\nopenssl req -x509 -newkey rsa:2048 -nodes -keyout /root/backup.key -out /backup/backup.pem -days 3650 -subj \"/CN=Backup Encryption\"\n```\n\nThe command generates 2 files:\n1. `/backup/public.pem`\n   The public key file used to encrypt the GZIP files;\n   This file can be safely stored in `/backup/`;\n   Use this like `readonly DB_ENCRYPTION_KEY=\"/backup/public.pem\"`.\n2. `/root/private.key`\n    This key file is required to decrypt the GZIP files;\n    Keep this on a safe location, for example `/root/backup.key`.\n\nDecryption can be done with:\n```bash\nopenssl smime -decrypt -inform DER -in EXAMPLE.sql.gz.enc -inkey /root/backup.key \u003e EXAMPLE.sql.gz\n```\n\n## Contributing\n\nAny bugs or ideas for improvement can be reported using GitHub's Issues thingy.\n\nIf you know `bash` or `pwsh` and see how the scripts can be improved, don't be\nshy and create a Pull Request.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperfacilis%2Fbackup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fperfacilis%2Fbackup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fperfacilis%2Fbackup/lists"}