Installing NixOS on a Raspberry Pi 3

- nixos rpi

The process of installing NixOS on a Raspberry Pi 3 is pretty straightforward, as they are fully supported upstream. However, the documentation is somewhat spread out and occasionally a bit outdated and/or confusing, so I thought it may be worthwhile to summarize my recent experience.

  $ curl https://raw.githubusercontent.com/zupo/nix/master/rpi.nix > /etc/nixos/configuration.nix

There were two changes I needed to make: since NixOS 19.09 the first volume no longer holds /boot but only the Raspberry Pi firmware files, so it no longers needs to be resized. Also the configuration option determining whether or not documentation will be installed now has a different name. These are the changes I applied to /etc/nixos/configuration.nix:

    # File systems configuration for using the installer's partition layout
    fileSystems = {
  -    "/boot" = {
  -      device = "/dev/disk/by-label/NIXOS_BOOT";
  -      fsType = "vfat";
  -    };
      "/" = {
        device = "/dev/disk/by-label/NIXOS_SD";
        fsType = "ext4";
  @@ -31,17 +31,23 @@
    };

    # Preserve space by sacrificing documentation and history
  -  services.nixosManual.enable = false;
  +  documentation.nixos.enable = false;
    nix.gc.automatic = true;

The file should now look like this:

  { config, pkgs, lib, ... }:
  {
    # NixOS wants to enable GRUB by default
    boot.loader.grub.enable = false;

    # if you have a Raspberry Pi 2 or 3, pick this:
    boot.kernelPackages = pkgs.linuxPackages_latest;

    # A bunch of boot parameters needed for optimal runtime on RPi 3b+
    boot.kernelParams = ["cma=256M"];
    boot.loader.raspberryPi.enable = true;
    boot.loader.raspberryPi.version = 3;
    boot.loader.raspberryPi.uboot.enable = true;
    boot.loader.raspberryPi.firmwareConfig = ''
      gpu_mem=256
    '';
    environment.systemPackages = with pkgs; [
      raspberrypi-tools
    ];

    # File systems configuration for using the installer's partition layout
      "/" = {
        device = "/dev/disk/by-label/NIXOS_SD";
        fsType = "ext4";
      };
    };

    # Preserve space by sacrificing documentation and history
    documentation.nixos.enable = false;
    nix.gc.automatic = true;
    nix.gc.options = "--delete-older-than 30d";
    boot.cleanTmpDir = true;

    # Configure basic SSH access
    services.openssh.enable = true;
    services.openssh.permitRootLogin = "yes";

    # Use 1GB of additional swap memory in order to not run out of memory
    # when installing lots of things while running other things at the same time.
    swapDevices = [ { device = "/swapfile"; size = 1024; } ];
  }
  $ nixos-rebuild switch
  $ nix-collect-garbage -d
  $ nixos-rebuild switch # removes now unused boot loader entries
  $ reboot
  users.users.pi = {
    isNormalUser = true;
    home = "/home/pi";
    extraGroups = [ "wheel" "networkmanager" ];
    openssh.authorizedKeys.keys = [ "ssh-dss AAAAB3Nza... pi@other" ];
  };

The extra groups allow the new user to execute commands as root via sudo and to configure the network. If you want to allow members of the wheel group to use sudo without a password, add the following option to your Nix configuration:

  security.sudo.wheelNeedsPassword = false;

With this new user in place we can also disable the permitRootLogin option in /etc/nixos/configuration.nix:

  - services.openssh.permitRootLogin = "yes";
  environment.systemPackages = [
    pkgs.vim
    pkgs.git
  ];

That’s it, have fun with NixOS on your Raspberry Pi 3.

Comments powered by Talkyard.