186 lines
5.2 KiB
Markdown
186 lines
5.2 KiB
Markdown
# Dotfiles
|
|
|
|
## NixOS
|
|
|
|
Install instructions for NixOS.
|
|
First open a shell with vim and git:
|
|
|
|
```bash
|
|
nix-shell -p git vim
|
|
```
|
|
|
|
### EXT4
|
|
|
|
```bash
|
|
parted /dev/nvme0n1 -- mklabel gpt
|
|
parted /dev/nvme0n1 -- mkpart ESP fat32 1MB 512MB
|
|
parted /dev/nvme0n1 -- mkpart root ext4 512MB 100%
|
|
parted /dev/nvme0n1 -- set 1 esp on
|
|
|
|
mkfs.fat -F 32 -n BOOT /dev/nvme0n1p1
|
|
mkfs.ext4 -L NixOS /dev/nvme0n1p2
|
|
|
|
mount /dev/disk/by-label/NixOS /mnt
|
|
mkdir -p /mnt/boot
|
|
mount -o umask=077 /dev/disk/by-label/BOOT /mnt/boot
|
|
nixos-generate-config --root /mnt
|
|
```
|
|
|
|
### ZFS
|
|
|
|
First stop the zfs-zed service, and unload the ZFS kernel modules:
|
|
```bash
|
|
systemctl stop zfs-zed
|
|
lsmod | grep zfs | cut -d' ' -f1 | xargs rmmod -f
|
|
```
|
|
|
|
Then add the following to `/etc/nixos/configuration.nix`:
|
|
```bash
|
|
boot.supportedFilesystems = [ "zfs" ];
|
|
```
|
|
|
|
And rebuild the system:
|
|
```bash
|
|
nixos-rebuild switch --upgrade
|
|
```
|
|
|
|
Partition the disk:
|
|
```bash
|
|
parted --script /dev/nvme0n1 -- mklabel gpt mkpart esp fat32 1MiB 512MiB mkpart primary 512MiB 100% set 1 boot on
|
|
```
|
|
|
|
Create an encrypted pool. The `-O` flags set filesystem properties that every
|
|
dataset inherits, so they only need to be given once here:
|
|
```bash
|
|
zpool create -f \
|
|
-o ashift=12 \
|
|
-o autotrim=on \
|
|
-O encryption=on -O keyformat=passphrase \
|
|
-O compression=zstd \
|
|
-O dnodesize=auto \
|
|
-O xattr=sa \
|
|
-O acltype=posixacl \
|
|
-O relatime=on \
|
|
-O redundant_metadata=most \
|
|
-O mountpoint=none \
|
|
rpool /dev/nvme0n1p2
|
|
```
|
|
|
|
Create the datasets. Keeping `/nix` separate from `/` means the store can be
|
|
excluded from snapshot and rollback policy, which is what makes an
|
|
erase-your-darlings setup possible later:
|
|
```bash
|
|
zfs create -o mountpoint=legacy rpool/root
|
|
zfs create -o mountpoint=legacy rpool/nix
|
|
zfs create -o mountpoint=legacy rpool/home
|
|
zfs create -o mountpoint=legacy -o recordsize=1M rpool/Storage
|
|
zfs create -o mountpoint=none -o refreservation=2G rpool/reserved
|
|
```
|
|
|
|
Mount them:
|
|
```bash
|
|
mkdir -p /mnt
|
|
mount -t zfs rpool/root /mnt
|
|
mkdir -p /mnt/nix /mnt/home /mnt/Storage
|
|
mount -t zfs rpool/nix /mnt/nix
|
|
mount -t zfs rpool/home /mnt/home
|
|
mount -t zfs rpool/Storage /mnt/Storage
|
|
```
|
|
|
|
#### Why these properties
|
|
|
|
Some of these can only be chosen when the pool or dataset is created, so they
|
|
are worth getting right the first time.
|
|
|
|
Creation-only, no way to change later without recreating the dataset:
|
|
|
|
- `encryption` and `keyformat` enable native ZFS encryption. This cannot be
|
|
turned on afterwards.
|
|
- `dnodesize=auto` allows dnodes larger than 512 bytes. Combined with
|
|
`xattr=sa` this keeps extended attributes inline instead of spilling into
|
|
separate blocks, which matters for a Nix store holding a hundred thousand
|
|
small files. Existing files keep whatever size they were written with.
|
|
- `ashift=12` matches the 4K physical sector size of modern NVMe drives.
|
|
|
|
Changeable later, but only applied to newly written blocks:
|
|
|
|
- `compression=zstd` gives a better ratio than the `lz4` that plain
|
|
`compression=on` selects. The Nix store compresses particularly well.
|
|
- `acltype=posixacl` is needed for systemd-journald to grant journal access
|
|
through ACLs. With the default of `off` that mechanism silently does nothing.
|
|
- `redundant_metadata=most` reduces the number of duplicate metadata writes.
|
|
- `recordsize=1M` suits bulk file storage. Leave it at the 128K default for
|
|
general purpose datasets, and drop it to 16K for databases or VM images.
|
|
- `autotrim=on` issues TRIM continuously. The `zpool-trim.timer` unit that
|
|
NixOS enables covers this periodically instead, so either approach works.
|
|
|
|
The `rpool/reserved` dataset never gets mounted. Its `refreservation` holds
|
|
space back so that the pool can be brought below its full mark by destroying
|
|
that one dataset. ZFS performance degrades noticeably above roughly 80%
|
|
capacity.
|
|
|
|
On a single disk pool there is no redundancy, so ZFS can detect corruption but
|
|
never repair it. Setting `copies=2` on the datasets that hold irreplaceable
|
|
data stores a second copy of each block at the cost of double the space:
|
|
```bash
|
|
zfs set copies=2 rpool/home
|
|
```
|
|
|
|
Snapshots are configured through `services.sanoid` in `hosts/Common/zfs.nix`.
|
|
ZFS dataset names are case sensitive, so an entry there has to match the
|
|
dataset exactly. A name that does not resolve leaves that dataset with no
|
|
snapshots at all while the service still reports success.
|
|
|
|
Format the boot partition:
|
|
```bash
|
|
mkfs.fat -F 32 -n BOOT /dev/nvme0n1p1
|
|
mkdir -p /mnt/boot
|
|
mount -t vfat /dev/nvme0n1p1 /mnt/boot
|
|
```
|
|
|
|
Generate the configuration:
|
|
```bash
|
|
nixos-generate-config --root /mnt
|
|
```
|
|
|
|
Add the following to /mnt/etc/nixos/configuration.nix:
|
|
```bash
|
|
boot.initrd.supportedFilesystems = [ "zfs" ];
|
|
boot.supportedFilesystems = [ "zfs" ];
|
|
services.zfs.autoScrub.enable = true;
|
|
|
|
networking.hostName = "Aloria";
|
|
networking.hostId = "abcdef01";
|
|
```
|
|
|
|
### Install
|
|
|
|
|
|
Then either clone the repository:
|
|
|
|
```
|
|
git clone https://git.thomasave.be/thomasave/Dotfiles
|
|
sudo nixos-install --impure --flake ./Dotfiles#Aloria
|
|
mv ./Dotfiles /mnt/home/user/.dotfiles
|
|
sudo ln -s /home/user/.dotfiles /mnt/etc/nixos
|
|
```
|
|
|
|
Or install it directly:
|
|
|
|
```
|
|
sudo nixos-install --impure --flake git+https://git.thomasave.be/thomasave/Dotfiles#Aloria
|
|
```
|
|
|
|
### Post-install
|
|
|
|
Clean-up:
|
|
```bash
|
|
umount /mnt/{home,nix,Storage,boot}
|
|
umount /mnt
|
|
```
|
|
|
|
If using ZFS:
|
|
```bash
|
|
zpool export -a
|
|
```
|