Skip to content

Instantly share code, notes, and snippets.

@chrisanthropic
Last active March 12, 2024 13:39
Show Gist options
  • Star 29 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save chrisanthropic/2e6d3645f20da8fd4c1f122113f89c06 to your computer and use it in GitHub Desktop.
Save chrisanthropic/2e6d3645f20da8fd4c1f122113f89c06 to your computer and use it in GitHub Desktop.
NixOS + Raspi4

Download the image builder

  • git clone git@github.com:Robertof/nixos-docker-sd-image-builder.git
  • cd nixos-docker-sd-image-builder

Configure for Raspi4

  • modify /config/rpi4/default.nix to increase size of boot partition
    • this step is optional but I ran out of space in /boot pretty quickly with the default setting since I'm still learning and rebuilding a lot. Let's leave some room for trial & error.
    • sdImage.firmwareSize = 1024;
  • modify /config/sd-image.nix
    • ./rpi3 becomes ./rpi4
    • "ssh-ed25519 ..." becomes your public key
  • modify /docker/docker-compose.yml
    • #DISABLE_ZFS_IN_INSTALLER: "y" becomes uncommented
      • Disables ZFS support in the installer. This can significantly reduce build times of the Raspberry Pi 4 image.

Build image

  • ./run.sh

Cleaup

  • ./run.sh down --rmi all -v

Burn image to sdcard

  • lsblk
  • dd bs=4M if=nixos-sd-image-20.03post-git-aarch64-linux.img of=/dev/sdX status=progress oflag=sync
    • /dev/sdX should be your sdcard listed in lsblk

SSH in

  • put the sdcard in your pi, plug your pi in to ethernet, plug in the power
  • wait a minute or so for the pi to boot and get an IP
  • I checked my router for the IP that was assigned
  • ping $IP
  • ssh -i ~/.ssh/$YOUR_PRIVKEY nixos@$IP

Generate base config

  • this will write a custom hardware config and the default configuration.nix file.
sudo su
nixos-generate-config
exit

Working Examples

Review your hardware config

  • cat /etc/nixos/hardware-configuration.nix
{ config, lib, pkgs, ... }:

{
  imports =
    [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
    ];

  boot.initrd.availableKernelModules = [ ];
  boot.initrd.kernelModules = [ ];
  boot.kernelModules = [ ];
  boot.extraModulePackages = [ ];

  fileSystems."/" =
    { device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888";
      fsType = "ext4";
    };

  fileSystems."/boot" =
    { device = "/dev/disk/by-uuid/2178-694E";
      fsType = "vfat";
    };

  swapDevices = [ ];

  nix.maxJobs = lib.mkDefault 4;
  powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
} 

Review and modify your system config

  • sudo su
  • vi /etc/nixos/configuration.nix
    • You'll want to update the username ($USERNAME), and ssh key ($YOUR_PUBLIC_KEY)
{ config, libs, pkgs, ... }:

{
  environment.systemPackages = with pkgs; [
    vim
  ];
  
  system.stateVersion = "20.03";
  imports =
    [ 
      ./hardware-configuration.nix
    ];

  boot = {
    loader.grub.enable = false;
    loader.raspberryPi.enable = true;
    loader.raspberryPi.version = 4;
    kernelPackages = pkgs.linuxPackages_rpi4;
  };

  console = {
    font = "Lat2-Terminus16";
    keyMap = "us";
  };
  
  # i18n.defaultLocale = "en_US.UTF-8";
  # time.timeZone = "America/Los_Angeles";
  
  networking = {
    hostName = "nixos";
    useDHCP = false;
    interfaces.eth0.useDHCP = true;
  };

  services.openssh = {
    enable = true;
    permitRootLogin = "yes";
    passwordAuthentication = false;
    challengeResponseAuthentication = false;
  };
  
  systemd.services.sshd.wantedBy = pkgs.lib.mkForce [ "multi-user.target" ];
  
  users.users.$USERNAME = {
    isNormalUser = true;
    home = "/home/$USERNAME";
    extraGroups = [ "wheel" "networkmanager" ];
    openssh.authorizedKeys.keys = [ "$YOUR_PUBLIC_KEY" ];
  };
  
}

Rebuild your system with your new config

  • nixos-rebuild switch

Create password for your new user

You'll need this to be able to use sudo

  • passwd $USERNAME
    • Replace $USERNAME with the actual username you created above

Test it

  • Reboot and SSH in
    • reboot
    • ssh -i ~/.ssh/$YOUR_KEY $YOUR_USERNAME@$PI_IP
  • test sudo
    • sudo su

Continue with basic configuration

  • locale
  • timzeone
  • hostname

(Optional) Setup Home Manager

(Optional) Graphics / Desktop Environment

  • xorg
  • alsa/pulse
  • graphics card driver
  • kde/plasma5

Useful links

Nest Steps

@Robertof
Copy link

Hey @chrisanthropic, I've added a mention to your great instructions on the SD image builder repo -- hopefully you won't mind!

https://github.com/Robertof/nixos-docker-sd-image-builder#raspberry-pi-3-and-4

@chrisanthropic
Copy link
Author

I don't mind at all @Robertof, thanks for the great build tool!

@Rawa
Copy link

Rawa commented Jun 24, 2020

Thanks you! Great work!

@Ramblurr
Copy link

Is it possible to use a variation of this method to create a bootable system image without the installer? I want to create an appliance-like sd image with bre-baked config running some services.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment