Home Restic Backups with Backblaze B2
Post
Cancel

Restic Backups with Backblaze B2

See Quickstart Guide for Restic and Backblaze B2 Cloud Storage

Install

Linux (Ubuntu)

I prefer to install from restic repo; the version packaged for ubuntu is several versions behind.

1
2
3
curl -L https://github.com/restic/restic/releases/download/v0.15.1/restic_0.15.1_linux_amd64.bz2 | bunzip2 -c > restic
chmod +x restic
sudo mv ./restic /usr/local/bin

Check for updates:

This only works if you installed from the restic repo.

1
sudo /usr/local/bin/restic self-update

Generate support files:

1
2
sudo restic generate --zsh-completion /usr/local/share/zsh/site-functions/_restic
sudo restic generate --man /usr/local/man/man1

Fuse is needed to mount backups:

1
sudo apt install -y fuse

Mac

1
brew install restic macfuse

Could instead install from restic repo.

Configure

Backblaze

One time:

  • Make a bucket in backblaze (“carlton-backups-restic”).
  • Edit Lifecycle settings to “Keep only the last version of the file”
  • Create an application key
    • Add a new application key
    • Name it carlton-backups-restic
    • Grant access to only the bucket we created for restic
    • Be sure to allow listing all bucket names

Note: I first tried using the S3 interface (per Restic Backblaze B2 instructions), but ran into errors “AccessDenied”. Supposedly the bug behind this was fixed, but I’m on the latest version and still encountered it.

Environment

On each client (substitute your own secrets):

1
2
3
4
5
6
7
sudo mkdir -p /etc/restic
cat <<EOF | sudo tee /etc/restic/restic-env
B2_ACCOUNT_ID=<YOUR B2 ACCOUNT ID>
B2_ACCOUNT_KEY=<YOUR B2 ACCOUNT KEY>
RESTIC_REPOSITORY=b2:carlton-backups-restic
RESTIC_PASSWORD_FILE=/etc/restic/restic-password
EOF

Note that you cannot use the form “export VAR=value” because this will be loaded by systemd (at least on Linux), it is not a shell script.

1
 echo <PASSWORD> | sudo tee /etc/restic/restic-password

Restrict access to a group you are part of (adm on ubuntu, or admin on Mac):

1
2
sudo chown root:adm /etc/restic/*
sudo chmod 440 /etc/restic/*

Create the Restic Repository

One time:

1
2
export $(cat /etc/restic/restic-env)
restic init

Usage

Backup a Directory

But see below for how to do this more simply with resticprofile.

If you need root permissions to read the directory:

1
sudo su - root -c '. /etc/restic/restic-env && restic -v backup --exclude-file=/etc/.excludes /etc'

Note: you can also do this with capabilities

Otherwise:

1
restic -v backup --exclude-file=$HOME/.excludes $HOME

or (this is simpler on Macs):

1
restic -v backup --files-form=$HOME/.includes $HOME

I follow the convention of keeping a file .excludes and/or a file .includes at the top level of directories being backed up.

Example Commands

Remember to load environment first:

1
export $(cat /etc/restic/restic-env)
  • restic snapshots
  • restic diff $snapshotID1 $snapshotID2
  • restic ls $snapshotID
  • restic forget $snapshotID
  • restic unlock
  • restic check -v --read-data-subset 100m # 1GB per day download is free with b2

Scheduling

Use resticprofile

Install

Linux

1
2
3
4
5
6
curl -L https://raw.githubusercontent.com/creativeprojects/resticprofile/master/install.sh -o /tmp/install.sh
chmod +x /tmp/install.sh
sudo /tmp/install.sh -b /usr/local/bin

# not clear if this works
# resticprofile generate --zsh-completion > /usr/local/share/zsh/site-functions/_resticprofile

Mac

1
2
brew tap creativeprojects/tap
brew install resticprofile

Configure

Sample /etc/restic/profiles.yaml, adjust directories to be backed up.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# /etc/restic/restic-env must be sourced to define these
# B2_ACCOUNT_ID
# B2_ACCOUNT_KEY
# RESTIC_REPOSITORY
# RESTIC_PASSWORD_FILE
#
# Environment variables can be access this way if needed:
#    password-file: \{\{ .Env.RESTIC_PASSWORD_FILE \}\}
#    repository: \{\{ .Env.RESTIC_REPOSITORY \}\}

version: 1

global:
  initialize: false
  priority: low
  min-memory: 100
  exclude-caches: true
  one-file-system: true
  verbose: true
  group-continue-on-error: true
  restic-lock-retry-after: 1m
  restic-stale-lock-age: 2h

groups:
  default:
    - etc
    - mike
    - shared

base:
  repository: "b2:carlton-backups-restic"
  password-file: "/etc/restic/restic-password"
  force-inactive-lock: true
  schedule-lock-wait: "15m"
  retention:
    after-backup: true    # runs forget after each backup
    host: true            # true => current host
    prune: true
    keep-hourly: false
    keep-daily: 7
    keep-weekly: 4
    keep-monthly: 12
    keep-yearly: 2

etc:
  inherit: base
  lock: "/tmp/resticprofile-profile-etc.lock"
  backup:
    source: "/etc"
    exclude-file: "/etc/.excludes"
    tag: etc
    schedule: "*-*-* 01:00:00"

mike:
  inherit: base
  lock: "/tmp/resticprofile-profile-mike.lock"
  backup:
    source: "/home/mike"
    exclude-file: "/home/mike/.excludes"
    tag: mike
    schedule: "*-*-* 01:30:00"

shared:
  inherit: base
  lock: "/tmp/resticprofile-profile-shared.lock"
  backup:
    source: "/var/shared"
    exclude-file: "/var/shared/.excludes"
    tag: shared
    schedule: "*-*-* 02:00:00"

Alternatively, if you want to backup several directories from one directory (i.e. just the important parts of your home directory), you can use --files-from; just remember you should not specify source: if you do this. E.g.

1
2
3
4
5
6
7
default:
  inherit: base
  lock: "/tmp/resticprofile-profile-mike.lock"
  backup:
    files-from: "/Users/mike/.includes"
    tag: mike
    schedule: "*-*-* 09:30:00"

and then in /Users/mike/.includes:

1
2
3
4
5
6
/Users/mike/Desktop
/Users/mike/Documents
/Users/mike/Pictures
/Users/mike/Movies
/Users/mike/Music
/Users/mike/Public

Schedule

Linux

To install or update systemd job:

1
sudo resticprocfile schedule

Need to update the created jobs to load restic variables:

1
2
3
4
for file in /etc/systemd/system/resticprofile-backup@profile-*.service; do
  echo 'EnvironmentFile=/etc/restic/restic-env' | sudo tee -a "$file"
  echo 'PassEnvironment=B2_ACCOUNT_ID B2_ACCOUNT_KEY RESTIC_REPOSITORY RESTIC_PASSWORD_FILE' | sudo tee -a "$file"
done

To remove them, use unschedule

Mac

First time, just do:

1
resticprofile schedule

Be sure to run manually as instructed.

To make changes to the profiles, just schedule again, but you may need to unload the agent first. The launch agent lives at something like Library/LaunchAgents/local.resticprofile.default.backup.agent.plist, so:

1
2
3
agent=Library/LaunchAgents/local.resticprofile.default.backup.agent.plist
launchctl unload "$agent"
resticprofile schedule

If you get errors, try:

1
2
launchctl unload "$agent"
launchctl load -w "$agent"

Also check local.resticprofile.default.backup.log

Note: you must add the B2 environment variables to the agent file each time you schedule.

Find the section EnvironmentVariables (it should have an entry for PATH already) and add these:

1
2
<key>B2_ACCOUNT_ID</key><string>YOUR B2 ACCOUNT ID</string>
<key>B2_ACCOUNT_KEY</key><string>YOUR B2 ACCOUNT KEY</string>

Run Launchctl on Demand

1
2
agent=Library/LaunchAgents/local.resticprofile.default.backup.agent.plist
launchctl start $agent

Examples

  • resticprofile --dry-run backup
  • resticprofile backup --dry-run
  • resticprofile etc.backup
  • 1
    2
    3
    
    mkdir -p /tmp/restic 
    resticprofile etc.mount /tmp/restic   # N.B. will mount all profiles regardless
    ls /tmp/restic/tags/etc/latest
    
This post is licensed under CC BY 4.0 by the author.