Automating backups with rsync and cron on Linux
A reliable backup should continue working when nobody remembers to run it. On Linux, rsync can transfer changed files efficiently, preserve important metadata and create versioned copies without transferring an entire directory every night. Cron then supplies the scheduling, turning those capabilities into a repeatable process for workstations, home servers and small business systems.
The difficult part is not typing a copy command. It is deciding what to protect, where the copies belong and how failures will be noticed. A useful automated backup also needs a tested restoration path, secure credentials and enough redundancy to survive a failed disk, an unavailable network or a power outage. The following approach treats rsync as the transport, cron as the trigger and a collection of checks as the safety net.
Set the backup boundary
Start with the data that cannot be recreated. For a home computer, that may include documents, photographs, account files and configuration directories. A small office might also need customer records, project archives, mail and accounting data. System directories can usually be rebuilt from installation media, while caches and downloaded packages can be excluded because they consume space without representing unique information.
Live databases require special care. Copying files while PostgreSQL, MySQL or another service is writing to them can produce an inconsistent snapshot. Export the database with its native backup tool first, then place that dump inside the rsync source tree. The resulting archive can then be copied safely alongside ordinary files. A backup that skips application-specific exports may look comprehensive while remaining impossible to restore.
Choose local and off-site destinations deliberately. The local copy protects against an accidental deletion and makes fast recovery practical, while the off-site copy handles theft, fire and destruction of the main computer. Australia’s geography makes this separation valuable: a household in Perth, Adelaide or Alice Springs may have slow fixed-line services, constrained mobile data or an internet connection that is vulnerable to local weather. Populated areas often have NBN service from providers such as Telstra, Optus or Aussie Broadband, and these fixed-line plans are commonly uncapped, but mobile broadband may include a data allowance.
Build and test the rsync operation
Rsync compares source and destination files, then transfers only the differences. The -a option preserves permissions, timestamps, symbolic links and other commonly required attributes, while -X preserves extended attributes and -H preserves hard links. SSH is a sensible transport because it encrypts the connection and avoids opening the unauthenticated rsync daemon port to the internet.
A basic local backup script can be as follows:
#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
source_dir=/home/
destination_dir=/mnt/backup-volume/workstation/daily/
mkdir -p "$destination_dir"
rsync -aAXH \
--delete-delay \
--partial \
--exclude='.cache/' \
--exclude='node_modules/' \
"$source_dir" "$destination_dir"
The trailing slash on source_dir copies the contents of /home rather than creating another nested home directory. Without it, the destination receives a home folder. The --delete-delay option removes obsolete files from a mirror destination, but it should be introduced only after administrators understand its effect. Exclusions receive particular care because a broad pattern can silently remove data that the destination still needs.
Test the operation with --dry-run before the first live transfer, then repeat the test after changing exclusions. Use the same SSH identity and destination on every run so rsync can compare ownership and permissions correctly. A first backup may take hours over a new broadband connection, but later runs should transfer only changed blocks and metadata. Check the exit status as well as the terminal output; rsync uses nonzero codes for partial transfers and other failures.
Custom administration tools deserve the same validation discipline. The approach shown in the Swift input validation guide illustrates why an interface should reject invalid paths and unexpected values before invoking a backup command. A Linux web panel should likewise prohibit shell metacharacters, restrict selectable directories and pass fixed arguments to the script rather than accepting an unrestricted command.
Schedule cron without surprises
Cron reads a crontab containing a schedule followed by an absolute command. The script should have a fixed location, a predictable owner and permissions that prevent accidental modification. Since cron starts with a minimal environment, it does not necessarily load the same shell configuration as an interactive login.
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
17 2 * * * /usr/local/sbin/backup-workstation >> /var/log/backup-workstation.log 2>&1
On Debian and Ubuntu, the service is usually called cron; on Fedora, RHEL and similar distributions it may be called crond. Both should be enabled at boot. The scheduled command should capture the exit status and send it to a monitoring service, because a backup that fails quietly is effectively absent. A lock such as flock can prevent a slow transfer from overlapping with the next scheduled run.
Daylight saving requires extra thought in Australia. In New South Wales, Victoria, South Australia and Tasmania, clocks move forward on the first Sunday in October and back on the first Sunday in April. Queensland, Western Australia and the Northern Territory do not observe it. Adelaide sits half an hour ahead of Perth and Sydney, while Lord Howe Island uses a 30-minute daylight-saving shift. A job scheduled for 02:17 can therefore be skipped or run twice around a clock transition.
Distributions using Cronie may support CRON_TZ=Australia/Sydney, while other implementations require the daemon’s timezone to be configured centrally. Test the transition dates on the actual server rather than assuming equivalent behaviour. Alternatively, schedule the work in UTC and confirm that its Australian local time remains sensible. The familiar reassurance that it will be “she’ll be right” is not an adequate recovery strategy; a missing run should trigger an alert and a documented retry.
Verify restores and monitor failures
A successful rsync exit code proves that a transfer completed, not that the copy can restore a working service. Schedule periodic restoration tests on another disk or test virtual machine. Select important files, compare checksums and restore a database export into an isolated location. A practical comparison can use rsync --dry-run --checksum --itemize-changes to reveal differences that timestamps alone would miss.
Keep logs outside the directory being synchronised, or rsync may copy its own output. Rotate them so that a small backup disk does not fill with historical records. Monitoring should check more than the existence of a log file: it should record the latest successful run, the transfer duration and the rsync exit status. If the backup finishes three hours late or the destination has not changed for several days, the monitoring should notify the responsible person through a channel that works independently of the backup network.
A simple status page can make failures easier to recognise. For a static interface, a visual cue can be prepared with the GIMP button icon guide, avoiding the need for a complete application when all that is required is a clear success or warning indicator. More importantly, the page should display the timestamp and status of the last verified run rather than merely claiming that the scheduler is active.
Restoration documentation belongs with the backup job. Record the destination paths, encryption details, required packages and the commands for restoring both files and databases. If the original machine can no longer boot, the procedure should still be understandable to another administrator. Passwords should be stored in a secure password manager, while a sealed copy of recovery keys can be kept separately from the hardware.
Harden the setup for Australian sites
Use SSH keys instead of storing a password in a cron script. A dedicated backup account on the destination system limits the damage caused by a compromised workstation. Restrict that account to the required directories, disable its interactive shell where practical and prevent direct access to unrelated system files. Protect private keys with appropriate permissions, and never place them inside the directory being copied.
Physical protection matters during an Australian summer. High ambient temperatures can shorten the life of drives and power supplies, while storms can interrupt mains electricity or damage networking equipment. A UPS, surge protection and temperature-aware enclosure reduce avoidable failures, but local equipment cannot defend against fire or smoke. Keep at least one copy away from the building, and test whether the off-site system can receive a connection during an NBN outage. Large initial uploads may need to be scheduled outside mobile data limits or peak congestion.
Australian organisations may also need to consider the Privacy Act 1988 and the Australian Privacy Principles when backups contain personal information. Limit administrative access, encrypt portable storage and define how obsolete copies are expired. Encryption does not replace access controls because anyone who can read an unencrypted mounted backup can recover the protected data.
Finally, verify permissions and ownership on the destination after each major configuration change. Run the job as a known account, protect the destination from accidental deletion and monitor free space before an rsync transfer begins. This produces a backup process that remains accountable to an administrator in Sydney, Melbourne or Darwin and continues to provide usable recovery when the original system cannot.