# Raspberry Pi SD Image Building and Deployment

Guide for building and deploying NixOS SD card images for Raspberry Pi hosts (e.g., stinky).

## Overview

Raspberry Pi hosts use a different deployment strategy than regular NixOS hosts:
- **First deployment**: Build and flash an SD card image
- **Subsequent updates**: Use `deploy-rs` like other hosts

## Architecture

### Storage Layout

**Partition structure** (automatically created by NixOS):
- `/boot/firmware` - FAT32 partition (label: `FIRMWARE`)
  - Contains Raspberry Pi firmware, U-Boot bootloader, device trees
- `/` - tmpfs (in-memory, ephemeral root)
  - 2GB RAM disk, wiped on every boot
- `/nix` - ext4 partition (label: `NIXOS_SD`)
  - Nix store and persistent data
  - Contains `/nix/persist` directory for impermanence

### Impermanence with tmpfs

Unlike btrfs-based hosts that use `/persist`, Pi hosts use `/nix/persist`:
- Root filesystem is tmpfs (no disk writes, auto-wiped)
- Single ext4 partition mounted at `/nix`
- Persistent data stored in `/nix/persist/` (directory, not separate mount)
- Better for SD card longevity (fewer writes)

**Persisted paths**:
- `/nix/persist/var/lib/nixos` - System state
- `/nix/persist/home/ppetru` - User home directory
- `/nix/persist/etc` - SSH host keys, machine-id
- Service-specific: `/nix/persist/var/lib/octoprint`, etc.

## Building the SD Image

### Prerequisites

- ARM64 emulation enabled on build machine:
  ```nix
  boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
  ```
  (Already configured in `workstation-node.nix`)

### Build Command

```bash
# Build SD image for stinky
nix build .#packages.aarch64-linux.stinky-sdImage

# Result location
ls -lh result/sd-image/
# nixos-sd-image-stinky-25.05-*.img.zst (compressed with zstd)
```

**Build location**: Defined in `flake.nix`:
```nix
packages.aarch64-linux.stinky-sdImage =
  self.nixosConfigurations.stinky.config.system.build.sdImage;
```

## Flashing the SD Card

### Find SD Card Device

```bash
# Before inserting SD card
lsblk

# Insert SD card, then check again
lsblk

# Look for new device, typically:
# - /dev/sdX (USB SD card readers)
# - /dev/mmcblk0 (built-in SD card slots)
```

**Warning**: Double-check the device! Wrong device = data loss.

### Flash Image

```bash
# Decompress and flash in one command
zstd -d -c result/sd-image/*.img.zst | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync

# Or decompress first, then flash
unzstd result/sd-image/*.img.zst
sudo dd if=result/sd-image/*.img of=/dev/sdX bs=4M status=progress conv=fsync
```

### Eject SD Card

```bash
sudo eject /dev/sdX
```
