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.
Download an image from Hydra, NixOS' CI tool. For the Pi 3 you'll use an AArch 64 image of the latest release (currently 20.03), which can be found here.
Flash the image on an SD card with a tool of your choice, e.g. Etcher or
dd
. If you don't have an HDMI cable available you'll also have to edit/extlinux/extlinux.conf
to configure the UART console. I had such a cable available and this post assumes you do to.The first type you boot from this card the NixOS installer will expand the volume, which can take a little bit of time.
Once the system booted, it's time to get a basic configuration set up. I started from zupo's config, who wrote one of the first comprehensive tutorials for NixPS on Raspberry Pi.
$ 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; } ];
}
- Time to build from the new minimal configuration, do some cleanup work and reboot just in case:
$ nixos-rebuild switch
$ nix-collect-garbage -d
$ nixos-rebuild switch # removes now unused boot loader entries
$ reboot
- Add a user account so we no longer need to SSH to the Pi as
root
. I opted for the declarative approach:
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";
- Add some system packages. For basic necessities I prefer the declarative approach over installation with
nix-env
, e.g.:
environment.systemPackages = [
pkgs.vim
pkgs.git
];
That's it, have fun with NixOS on your Raspberry Pi 3.
Discussion (0)