{"id":52,"date":"2024-12-29T10:20:00","date_gmt":"2024-12-29T07:20:00","guid":{"rendered":"https:\/\/fsaeed.blog\/?p=52"},"modified":"2026-10-31T00:18:52","modified_gmt":"2026-10-30T21:18:52","slug":"encrypted-automatic-backups-with-restic","status":"publish","type":"post","link":"https:\/\/fsaeed.blog\/index.php\/2024\/12\/29\/encrypted-automatic-backups-with-restic\/","title":{"rendered":"Encrypted, Automatic Backups with restic"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Hello, tech enthusiasts! \ud83d\udc4b<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The end of the year is a good time for a question: if your laptop died today, what would you lose? Your reports, your scripts, your invoice archive?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Many people copy files to a USB disk &#8220;sometimes&#8221;. But sometimes means &#8220;not last month&#8221;. And a plain copy on a disk is readable by anyone who finds that disk.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Today we fix both problems with <strong>restic<\/strong>. It makes backups that are encrypted, small, and automatic.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What you need<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A Linux or Mac computer (restic also works on Windows)<\/li>\n\n\n<li>An external disk, or a server you can reach with SFTP<\/li>\n\n\n<li>restic, free from <a href=\"https:\/\/restic.net\">https:\/\/restic.net<\/a><\/li>\n\n\n<li>About 20 minutes<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Understand how restic works<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">restic keeps your backups in a <strong>repository<\/strong>. A repository is a folder that holds all your backups, locked with a password. Inside, everything is <strong>encrypted<\/strong>: without the password, the data is just noise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Each backup is called a <strong>snapshot<\/strong>. A snapshot is like a photo of your folders at one moment. restic is smart: it only stores the parts of files that changed. So 30 nightly snapshots do not take 30 times the space.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Install restic<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">On Ubuntu or Debian:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install restic<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a Mac with Homebrew:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>brew install restic<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create the repository<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">First, choose a strong password and store it in a file only you can read:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/.config\/restic\nnano ~\/.config\/restic\/password     # type a long password, save\nchmod 600 ~\/.config\/restic\/password<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now tell restic where things are. We use <strong>environment variables<\/strong>, which are like sticky notes the terminal can read:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export RESTIC_REPOSITORY=\/media\/backupdisk\/restic-repo\nexport RESTIC_PASSWORD_FILE=~\/.config\/restic\/password\nrestic init<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using a server instead of a disk? Use an SFTP address. Your SSH key login must already work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export RESTIC_REPOSITORY=sftp:backupuser@backup.example.com:\/srv\/restic-repo\nrestic init<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Very important:<\/strong> if you lose the password, your backups are gone forever. Nobody can open them, not even you. Save a copy of the password in a password manager or on paper in a safe place.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Make your first backup<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>restic backup ~\/Documents ~\/Scripts --exclude \"*.tmp\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first backup takes the longest. Later ones are much faster. Let us check what we have:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>restic snapshots<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will see a list with an ID, date, and folders for each snapshot.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Restore one file<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is the reason we do backups. Say you deleted <code>sales_2024.xlsx<\/code> by mistake. First, find it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>restic find sales_2024.xlsx<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then restore it from the latest snapshot into a safe folder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>restic restore latest --target ~\/restored --include \"\/home\/youruser\/Documents\/sales_2024.xlsx\"<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The file appears inside <code>~\/restored<\/code>, with its full folder path. Check it, then copy it back. You can also use a snapshot ID instead of <code>latest<\/code> to go further back in time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tip: test a restore now, while nothing is wrong. A backup you never tested is only a hope.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6: Clean up old snapshots<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You do not need every nightly snapshot forever. Tell restic which ones to keep:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This keeps the last 7 days, the last 4 weeks, and the last 6 months. <code>forget<\/code> removes the old snapshots from the list. <code>--prune<\/code> actually deletes the data nobody needs anymore, to free space.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once in a while, check that the repository is healthy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>restic check<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7: Make it automatic with cron<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Cron<\/strong> is the Linux alarm clock. It runs commands at fixed times. First, put everything in a small script, <code>~\/backup.sh<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# Nightly restic backup\nexport RESTIC_REPOSITORY=\/media\/backupdisk\/restic-repo\nexport RESTIC_PASSWORD_FILE=$HOME\/.config\/restic\/password\n\nrestic backup ~\/Documents ~\/Scripts --exclude \"*.tmp\" &amp;&amp;\nrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make it runnable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chmod 700 ~\/backup.sh<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Open your cron list with <code>crontab -e<\/code> and add this line. It runs the script every night at 02:00 and writes a log:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0 2 * * * $HOME\/backup.sh &gt;&gt; $HOME\/backup.log 2&gt;&amp;1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Check <code>backup.log<\/code> the next morning to see that it worked.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Common problems<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>&#8220;Fatal: unable to open config file&#8221;<\/strong> \u2192 The repository path is wrong, or the disk is not plugged in.<\/li>\n\n\n<li><strong>&#8220;wrong password or no key found&#8221;<\/strong> \u2192 Check the password file. There must be no extra spaces.<\/li>\n\n\n<li><strong>&#8220;repository is already locked&#8221;<\/strong> \u2192 An old backup was stopped halfway. If no backup is running now, run <code>restic unlock<\/code>.<\/li>\n\n\n<li><strong>Cron job does nothing<\/strong> \u2192 Cron uses a very small environment. Use full paths in the script, and read <code>backup.log<\/code>.<\/li>\n\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Wrap-up<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You now have backups that are encrypted, run every night, and clean up after themselves. And you know how to get a single file back in under a minute.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next idea: follow the &#8220;3-2-1&#8221; rule. Keep 3 copies of your data, on 2 different kinds of storage, with 1 copy in another place. A second restic repository on a remote server is an easy way to get there. \ud83d\udd10<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Set up encrypted backups that run by themselves every night, and learn how to get a lost file back.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[30,33,27,31,32],"class_list":["post-52","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-backup","tag-cron","tag-linux","tag-restic","tag-security"],"_links":{"self":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/52","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/comments?post=52"}],"version-history":[{"count":1,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"predecessor-version":[{"id":81,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/posts\/52\/revisions\/81"}],"wp:attachment":[{"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fsaeed.blog\/index.php\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}