wip(rpi4): park the Pi 4 sketch — superseded by the Pi 5 machinery in #87

Never-committed working tree state found in the dev worktree: a Pi 4 hardware
module, a setup walkthrough, an upboard-serial refactor, and flake wiring that
does not evaluate (aarch64 packages block nested inside packages.x86_64-linux;
pkgs-aarch64 built with `inherit aarch64` instead of `system`, so it is really
x86; references a nixosConfigurations.rpi4-installed that is never defined).

Parked verbatim for reference. The real Pi 4 target is rebuilt on top of #87's
mkPiInstalled/mkPiImage shape in feat/rpi4-target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013A6683cCHnQxFUosx1krY4
This commit is contained in:
Padreug 2026-09-20 11:17:41 +02:00
commit 7e59951fcc
7 changed files with 533 additions and 4 deletions

View file

@ -14,7 +14,8 @@ deploy/nixos/
├── hardware/
│ ├── douro.nix # Dell OptiPlex 9030 AIO (stock Douro motherboard; SATA SSD, eGalax touch)
│ ├── batm3.nix # GeneralBytes BATM3 chassis with a Dell OptiPlex 9030 AIO grafted in (custom mod; WireGuard wired in)
│ └── upboard.nix # Aaeon UP Board (Sintra + tejo; eMMC root via sdhci-acpi + mmc_block)
│ ├── upboard.nix # Aaeon UP Board (Sintra + tejo; eMMC root via sdhci-acpi + mmc_block)
│ └── raspberry-pi4.nix # Raspberry Pi 4 (aarch64) hardware configuration
├── udev/
│ └── 99-bitspire-hardware.rules # additional udev rules (loaded via configuration.nix)
├── provision-atm.sh # Push LNbits credentials to a deployed ATM via SSH
@ -34,7 +35,7 @@ Each ATM model has two flake outputs:
| `packages.x86_64-linux.iso-<model>` | ISO | ISO image of the live variant |
| `packages.x86_64-linux.disk-image-<model>` | raw image | dd-able full disk image of the installed variant |
Models: `douro`, `tejo`, `sintra`, `batm3`.
Models: `douro`, `tejo`, `sintra`, `batm3`, `rpi4`.
```bash
# Build a Sintra disk image
@ -43,11 +44,111 @@ nix build .#disk-image-sintra
# Build a live ISO for tejo
nix build .#iso-tejo
# Build a Raspberry Pi 4 disk image (aarch64)
nix build .#disk-image-rpi4
# → result/nixos.img (Raspberry Pi firmware bootloader, GPT+ESP)
```
## Deploying to Sintra (full walkthrough)
The Sintra ships from the factory with whatever its previous OS was — Android, vendor Linux, or wiped. You need an Alpine live USB to act as your installer.
The Sintra ships from the factory with whatever its previous OS was — Android, vendor Linux, or wiped.
## Deploying to Raspberry Pi 4 (full walkthrough)
The Raspberry Pi 4 uses an SD card as primary storage and boots via the Raspberry Pi firmware bootloader (rpi-bootloader). Unlike Intel-based ATMs that use systemd-boot, the RPi4 config uses the native Raspberry Pi bootloader.
### Prerequisites
- Raspberry Pi 4 board (4GB or 8GB RAM recommended for Electron)
- 32GB+ SD card (or external SSD for better reliability)
- Network connection (ethernet recommended for stability)
- SSH access or a serial console (UART) for first-boot provisioning
### Build the disk image
```bash
nix build .#disk-image-rpi4
# → result/nixos.img (raw disk image, aarch64)
```
### Flash to SD card
```bash
# Replace /dev/sdX with your SD card device
sudo dd if=result/nixos.img of=/dev/sdX bs=4M status=progress conv=fsync && sync
```
**Important:** Verify the target is the SD card, not your main disk:
```bash
lsblk -f /dev/sdX
# Should show 'SD_CARD' or similar, not a hard drive name
```
### Boot and provision
1. Insert the SD card into the Raspberry Pi 4.
2. Connect Ethernet and power on.
3. Wait for boot (you should see Raspberry Pi firmware loading messages).
4. The kiosk screen should show "ATM unavailable — needs provisioning".
From your dev box, provision LNbits credentials:
```bash
LNBITS_SERVER_PUBKEY=$(docker logs <lnbits-container> 2>&1 | \
grep -oP 'Public key \(share this\):\s*\K[a-f0-9]{64}' | tail -1)
RELAY_URL=ws://<dev-lan-ip>:5001/nostrrelay/test \
LNBITS_SERVER_PUBKEY="$LNBITS_SERVER_PUBKEY" \
ATM_PRIVATE_KEY=$(openssl rand -hex 32) \
bash deploy/nixos/provision-atm.sh <rpi4-ip> 22
```
The script SSHes to `bitspire@<rpi4-ip>:22`, writes `/var/lib/bitspire/.env`, and restarts `bitspire.service`. After a few seconds the kiosk connects to LNbits over nostr-transport and shows the live UI.
### First-time deploy
**Save the generated `ATM_PRIVATE_KEY`.** LNbits identifies this ATM by its public key; if you regenerate the key on re-provision, LNbits will auto-create a fresh wallet and the old wallet's balance becomes inaccessible.
### Re-flash
To preserve the ATM's identity and transaction history, backup the `.env` and `state.db` from the running Raspberry Pi before reflashing:
```bash
# From the Raspberry Pi
mkdir -p ~/rpi4-backup-$(date +%Y%m%d)
cp /var/lib/bitspire/.env ~/rpi4-backup-$(date +%Y%m%d)/
cp /var/lib/bitspire/state.db ~/rpi4-backup-$(date +%Y%m%d)/
# Copy to dev box
scp bitspire@<rpi4-ip>:~/rpi4-backup-*/.env ~/rpi4-backup-*/
scp bitspire@<rpi4-ip>:~/rpi4-backup-*/state.db ~/rpi4-backup-*/
```
On re-flash, source the backup values:
```bash
set -a; source ~/rpi4-backup-<date>/.env; set +a
ATM_PRIVATE_KEY=$VITE_ATM_PRIVATE_KEY \
LNBITS_SERVER_PUBKEY=$VITE_LNBITS_SERVER_PUBKEY \
RELAY_URL=$VITE_RELAY_URL \
bash deploy/nixos/provision-atm.sh <rpi4-ip> 22
```
### Hardware-specific notes
- **Storage:** SD cards are slower and have limited write cycles compared to SSDs. Consider using a high-quality card and avoid frequent rewrites. For production, an external SSD via USB 3.0 is recommended for better reliability.
- **Power:** The Raspberry Pi 4 can draw up to 3A at 5V. Use a reliable power supply rated for at least 5V 3A.
- **Thermal:** The Pi 4 runs warm. Ensure adequate cooling (passive heatsinks or a fan) for 24/7 operation.
- **Console:** The serial console is available at `/dev/ttyAMA0` (PL011 UART) at 115200 baud, useful for debugging.
- **Swap:** A 2GB swapfile is enabled by default to prevent hard-freeze under memory pressure. Consider increasing this on 4GB models.
### Troubleshooting
- **Boot fails:** Check the SD card is properly flashed and inserted. Try rebuilding the image with a fresh `nix build .#disk-image-rpi4`.
- **No network:** Verify the Ethernet cable is connected and the Pi's lights show activity. Check `/etc/resolv.conf` after boot.
- **ATM doesn't connect to LNbits:** Verify `VITE_RELAY_URL` and `VITE_LNBITS_SERVER_PUBKEY` are set in `/var/lib/bitspire/.env` via SSH: `ssh bitspire@<rpi4-ip> 'cat /var/lib/bitspire/.env'`.
- **Electron fails to start:** Check memory usage (`free -h`). On 4GB models, close other processes to free up RAM. You need an Alpine live USB to act as your installer.
### 0. (Re-flash only) Preserve state from the existing Sintra