dotfiles/docs/server-installer-usb.md
Danny cda9c4cf0f sunken-ship: drop python-telegram-bot from fitness-bot pythonEnvs
bot.py was deleted upstream — neither prod nor shipyard launches a
polling bot anymore. server.py only needs python-dotenv + aiohttp.
Also refresh the prod section's comment + service description to
reflect the Mini-App-only architecture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 11:51:20 +02:00

5.4 KiB

Server installer USB (NixOS + LUKS)

Bootable USB that installs NixOS on a new server with disk encryption (LUKS). The install script handles partitioning, encryption, dotfiles cloning, SSH key setup, and hardware config generation. Only required inputs: hostname, LUKS passphrase, and target disk.

Quick path (Ethernet server like phantom-ship)

Prep (on sunken-ship or any Linux box)

  1. Download the NixOS minimal ISO on sunken-ship.
  2. Plug in USB and write the ISO:
    # Find your USB device (e.g. /dev/sdc)
    lsblk
    sudo dd if=nixos-minimal-*.iso of=/dev/sdX status=progress bs=4M
    sync
    

Install (on the new server)

  1. Boot the new machine from USB, plug in Ethernet, verify connectivity (ping 8.8.8.8).

  2. Start SSH on the live system so you can paste commands from your Mac:

    sudo systemctl start sshd
    sudo passwd nixos
    hostname -I   # note the IP
    
  3. From your Mac, scp your SSH public key and SSH in:

    scp ~/.ssh/id_ed25519_phantom_ship.pub nixos@<IP>:/tmp/key.pub
    ssh nixos@<IP>
    
  4. Run the bootstrap (one command):

    curl -sL https://raw.githubusercontent.com/DannyDannyDanny/dotfiles/main/scripts/bootstrap-install.sh | \
      INSTALLER_HOSTNAME=phantom-ship SSH_PUBKEY_FILE=/tmp/key.pub sudo -E bash
    

    This will prompt for: target disk, optional danny password, confirmation, and LUKS passphrase (twice: once for disko, once for post-install provisioning).

    The script automatically:

    • Partitions and encrypts the disk (LUKS + ext4)
    • Installs NixOS with the hostname
    • Clones dotfiles to /etc/dotfiles
    • Installs your SSH public key
    • Generates phantom-ship-hardware.nix
  5. Reboot, remove USB, unlock LUKS.

After first boot

  1. SSH in: ssh danny@phantom-ship
  2. First rebuild to switch from generic server-install to phantom-ship config:
    cd /etc/dotfiles && sudo nixos-rebuild switch --flake .#phantom-ship
    
  3. Commit the generated phantom-ship-hardware.nix back to the repo.

Environment variables

All optional; skip interactive prompts or add automation:

Variable Description
INSTALLER_HOSTNAME Skip hostname prompt
INSTALLER_DISK Skip disk prompt (validated as block device)
SSH_PUBKEY_FILE Path to .pub file; installed to danny's authorized_keys
FLAKE_REF Override flake reference (default: auto-detect from repo)
INSTALLER_SYSTEM_CONFIG_FILE JSON file merged into --system-config (e.g. WiFi config)

Cannot build the custom ISO on macOS (x86_64-linux only). Use the official NixOS minimal ISO:

  1. Download from nixos.org.
  2. Write to USB from sunken-ship or any Linux box.
  3. Boot, connect Ethernet, run bootstrap.

Option B: Custom ISO (build on Linux only)

Adds WiFi kernel modules for servers that need WiFi on the live system.

Build from sunken-ship

./scripts/build-installer-iso-on-server.sh

Build directly on Linux

cd ~/dotfiles && nix build .#installer-iso
# Write to USB:
sudo dd if=result/iso/nixos-minimal-*.iso of=/dev/sdX status=progress bs=4M

Live-system WiFi (optional, custom ISO only)

The minimal installer ISO runs NetworkManager, so live-system WiFi must be a declarative NetworkManager profile. networking.wireless / wpa_supplicant does not work here — NixOS asserts you cannot combine networking.networkmanager with networking.wireless.networks.

Create nixos/installer-wifi.nix (gitignored — it holds the PSK):

{
  networking.networkmanager.ensureProfiles.profiles.installer-wifi = {
    connection = {
      id = "installer-wifi";
      type = "wifi";
    };
    wifi = {
      mode = "infrastructure";
      ssid = "YourSSID";
    };
    wifi-security = {
      auth-alg = "open";
      key-mgmt = "wpa-psk";
      psk = "your-password";
    };
    ipv4.method = "auto";
    ipv6.method = "auto";
  };
}

flake-modules/installer-iso.nix auto-includes this file when present (via a builtins.pathExists check) — no flake edit needed. Because the file is gitignored, the flake only sees it once it is staged:

  • build-installer-iso-on-server.sh copies the file to the build host and runs git add -f automatically.
  • For a direct nix build, run git add -f nixos/installer-wifi.nix first (staging is enough — never commit it; it contains the PSK).

Then rebuild the ISO on Linux.

Installed-system WiFi (optional)

Pass a JSON file with wireless config:

sudo INSTALLER_SYSTEM_CONFIG_FILE=/path/to/wifi.json INSTALLER_HOSTNAME=my-server ./scripts/nixos-server-install.sh

Manual install (without the script)

sudo nix run github:nix-community/disko/latest#disko-install -- \
  --flake 'path:/tmp/dotfiles#server-install' \
  --disk main /dev/sda \
  --system-config '{"networking":{"hostName":"my-server"}}'

Summary

Step Action
Prep Download NixOS minimal ISO on sunken-ship, write to USB
Boot Boot new server from USB, plug Ethernet
Install curl ... | INSTALLER_HOSTNAME=phantom-ship SSH_PUBKEY_FILE=/tmp/key.pub sudo -E bash
Reboot Remove USB, unlock LUKS
First rebuild sudo nixos-rebuild switch --flake /etc/dotfiles#phantom-ship
Commit Push generated phantom-ship-hardware.nix to repo