raspberry pi 4: nas and home server
Completed build
Component list
- Raspberry Pi 4 (4GB)
- Raspberry Pi official USB-C power supply
- 2x Gigabyte 1TB SSD
- 2x StarTech.com USB 3.0 to SATA HDD/SSD Adapter Cable
- TerraPi Alpha case: dual SSD (link)
- 52Pi Low-Profile ICE Tower Cooling Fan
Build notes
The build is pretty simple, these notes are where I diverged from the instructions that came with each of the components.
Cooler + Alpha case compatibility
As can be seen in this official picture, the alpha pi case comes with a fan attachment for the top.
I wanted to use the ICE Tower cooler instead. This is possible as the ICE Tower cooler comes with copper standoffs that will screw (upside down) into the alpha pi case. The cooler can be mounted with the included screws into the upside-down standoffs.
Setup
OS
I installed the 64bit version of Ubuntu server, this has good support for ZFS.
The OS is installed on partitions on one of the SSDs. This was done using the official Raspberry Pi Imager tool.
There following partitions exist;
Disk1
- /dev/sda1: 256MB FAT 32 boot partition
- /dev/sda2: 8GB ext4 OS partition
- /dev/sda3: 950GB unformatted partition for ZFS
Disk2
- /dev/sdb1: 950GB unformatted partition for ZFS
- /dev/sdb2: 2GB linux swap partition
Overclock
The tower cooler is so effective that I overclocked the pi from 1500MHz to 2GHz with the following config;
/boot/firmware/config.txt
|
|
ZFS
The data partitions for zfs are not created with a filesystem.
The two disks are setup as a single mirrored vdev.
|
|
I created a parent-dataset at;
/tank/d1
|
|
No data should be written directly into the zpool, without using a dataset.
ZFS tuning
I set the following options for better performance.
Pool options
ashift=12
: set the disk block size to 4k (standard for SSDs post 2011)autoexpand=on
: allow the disks to autoexpand if replaced
Dataset options
atime: off
: don’t store the last accessed timecompression: lz4
: compress data on diskrecordsize: 1M
: most data will be media and images, better performancexattr: sa
: store attribute data in nodes, and not in filesystem
Snapshots
I use github.com/jimsalterjrs/sanoid to create automated and expiring snapshots on a schedule. I use the default schedule of;
- 36x hourly snapshots
- 30x daily snapshots
- 12x monthly snapshots
- 0x yearly snapshots
To restore the entire snapshot you can rollback, to access a specific file you can mount the snapshot and navigate to the file.
Snapshots help defend against accidental deletion.
Backup
I create a series of encrypted tar backups, that I store in an s3 bucket, to ensure that I have a remote / offsite copy of my data.
Data certainty
I have decided that I should defend against;
- single drive failure
- defence: zfs mirrored drives and backups to s3
- accidental deletion
- defence: snapshots, and backups to s3
- catastrophic failures
- defence: backup to s3
Software
- syncthing: syncing data between devices
- avahi-daemon: access using
<hostname>.local
on local network - wiki.js: home wiki, for me and my partner