Unopinionated Nix flake for infrastructure, vendor packages, kernel, and some optimized third-party packages for NixOS running on Raspberry Pi devices.
It will let you deploy NixOS fully declaratively in one step with tools like nixos-anywhere.
Provisions and manages Raspberry Pi firmware partition /boot/firmware
. Partition is being provisioned on nixos generation switch (integrated with bootloader activation scripts, as opposed to oneshot systemd services, for example), enabling to use deployment tools like nixos-anywhere
without any interactive intervention.
Supported boot methods: kernelboot
, uboot
. Also mostly-working uefi
in a separate branch.
inputs = {
nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi";
};
# Optional: Binary cache for the flake
nixConfig = {
extra-substituters = [
"https://nixos-raspberrypi.cachix.org"
];
extra-trusted-public-keys = [
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
];
};
There're helper functions intended to be used as a drop-in replacement for
nixpkgs.lib.nixosSystem
:
nixos-raspberrypi.lib.nixosSystem
nixos-raspberrypi.lib.nixosSystemFull
- same as above, but with RPi-optimized overlays applied globally, this may lead to more rebuildsnixos-raspberrypi.lib.nixosSystemInstaller
- same asnixosSystemFull
but with additional installer-specific modules
All of them take the following additional optional arguments:
nixpkgs
– default = nixpkgs of thenixos-raspberrypi
will be usedtrustCaches
– default=true, trust binary caches ofnixos-raspberrypi
nixosConfigurations.rpi5-demo = nixos-raspberrypi.lib.nixosSystem {
specialArgs = inputs;
modules = [
{
# Hardware specific configuration, see section below for a more complete
# list of modules
imports = with nixos-raspberrypi.nixosModules; [
raspberry-pi-5.base
raspberry-pi-5.display-vc4
raspberry-pi-5.bluetooth
];
}
({ config, pkgs, lib, ... }: {
networking.hostName = "rpi5-demo";
system.nixos.tags = let
cfg = config.boot.loader.raspberryPi;
in [
"raspberry-pi-${cfg.variant}"
cfg.bootloader
config.boot.kernelPackages.kernel.version
];
})
# ...
];
};
See also: https://github.com/nvmd/nixos-raspberrypi-demo, Installers and examples.
See flake.nix
, nixosModules
for a full list of configuration modules for your hardware.
Here is the list of the most important:
imports = with nixos-raspberrypi.nixosModules; [
# Base board support modules
raspberry-pi-02.base
raspberry-pi-4.base
raspberry-pi-5.base
# (Potentially) All boards
usb-gadget-ethernet # Configures USB Gadget/Ethernet - Ethernet emulation over USB
# RPi4:
# import this if you have the display, on rpi4 this is the only display configuration option
raspberry-pi-4.display-vc4
# RPi5:
# use one of following for the "PrimaryGPU" configuration:
raspberry-pi-5.display-vc4 # "regular" display connected
raspberry-pi-5.display-rp1 # for RP1-connected (DPI/composite/MIPI DSI) display
];
Sane default configuration is provided by the base module for a corresponding Raspberry board, but further configuration is, of course, possible:
Configuration options for the bootloader are in boot.loader.raspberryPi
(defined in modules/system/boot/loader/raspberrypi/default.nix
).
Raspberry's config.txt
can be configured with hardware.raspberry-pi.config
options, see modules/configtxt.nix
as an example (this is the default configuration as provided by RaspberryPi OS, but translated to nix format).
Options for a more fine-grained control:
- see implementation details in
lib/default.nix
,lib/internal.nix
- Use
nixos-raspberrypi.lib.int.nixosSystemRPi
instead ofnixos-raspberrypi.lib.nixosSystem
- Use regular
nixpkgs.lib.nixosSystem
importing the modules manually, see below
imports = with nixos-raspberrypi.nixosModules; [
# Required: Add necessary overlays with kernel, firmware, vendor packages
nixos-raspberrypi.lib.inject-overlays
# Binary cache with prebuilt packages for the currently locked `nixpkgs`,
# see `devshells/nix-build-to-cachix.nix` for a list
trusted-nix-caches
# Optional: All RPi and RPi-optimised packages to be available in `pkgs.rpi`
nixpkgs-rpi
# Optonal: add overlays with optimised packages into the global scope
# provides: ffmpeg_{4,6,7}, kodi, libcamera, SDL2, vlc, etc.
# This overlay may cause lots of rebuilds (however many
# packages should be available from the binary cache)
nixos-raspberrypi.lib.inject-overlays-global
];
The flake provides installation SD card images for Raspberry Pi Zero2, 4, and 5, that can also double as configuration examples in addition to demo configurations provided in https://github.com/nvmd/nixos-raspberrypi-demo.
See nixosConfigurations.rpi{02,4,5}-installer
in flake.nix
.
SD image can be built with:
$ nix build .#installerImages.rpi02
$ nix build .#installerImages.rpi4
$ nix build .#installerImages.rpi5
Replace # YOUR SSH PUB KEY HERE #
in custom-user-config
with your SSH public key. Network access to RPi02 is also possible via USB Gadget/Ethernet functionality.
.#nixosConfigurations.rpi{02,4,5}-installer.config.system.build.toplevel
are included in the binary cache.
for example, with nixos-anywhere
to the system running installer image (will use disko to set the disks up):
$ nixos-anywhere --flake .#<system> root@<hostname>"
or, to an already running system (change configuration of):
$ nixos-rebuild switch --flake .#<system> --target-host root@<hostname>
An alternative ways to consume individual packages without overlays are:
- to get it directly from the flake, it will based on stable
nixpkgs
without any of other optimisations transitively applied (i.e. only this particular package is optimised):
environment.systemPackages = [
nixos-raspberrypi.packages.aarch64-linux.vlc
];
- to get it from
nixos-raspberrypi.legacyPackages.<system>
. Here all overlays are applied.
This is basically boot.loader.raspberryPi
options, which are deprecated in nixpkgs, but updated and improved upon.
Design objectives:
- individually consumable modules and overlays for specific functions
- reuse of the existing nixos/nixpkgs infrastructure and idiomatic approaches to the maximum extent possible
- integration with the existing nixos system activation
This project grew naturally out of the need to configure and extend rather great tstat's raspberry pi support repository, which we used for some time.
Unfortunately it was virtually possible to work with without reengineering the whole thing, so this Flake was born. Inability to use it non-interactively with nixos-anywhere
was the biggest concern.
We found boot.loader.raspberryPi
options to be much more idiomatic, easier to extend, and maintain.
This flake strives to keep and improve those properties by keeping it as unopinionated as possible and modular (see above)
We're still using some ot the modules provided by an adapted fork of tstat/raspberry-pi-nix, namely config.txt
generation module.