{"id":14109170,"url":"https://github.com/lucernae/nixos-pi","last_synced_at":"2025-04-04T17:05:15.338Z","repository":{"id":54840078,"uuid":"324644460","full_name":"lucernae/nixos-pi","owner":"lucernae","description":"How to install NixOS on raspberry PI","archived":false,"fork":false,"pushed_at":"2025-03-10T15:38:58.000Z","size":52,"stargazers_count":177,"open_issues_count":7,"forks_count":30,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T16:04:35.738Z","etag":null,"topics":["github-action","nixos","nixos-pi","raspberry-pi","sd-card"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lucernae.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-26T22:20:24.000Z","updated_at":"2025-03-28T03:29:37.000Z","dependencies_parsed_at":"2023-02-04T07:01:19.225Z","dependency_job_id":"ca8ced62-e27d-459f-8195-ad519c8ab5da","html_url":"https://github.com/lucernae/nixos-pi","commit_stats":{"total_commits":20,"total_committers":2,"mean_commits":10.0,"dds":0.35,"last_synced_commit":"d45db1b773f6d5d508d7668b514d1e6a40ecaa3d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucernae%2Fnixos-pi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucernae%2Fnixos-pi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucernae%2Fnixos-pi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lucernae%2Fnixos-pi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lucernae","download_url":"https://codeload.github.com/lucernae/nixos-pi/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217172,"owners_count":20903008,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github-action","nixos","nixos-pi","raspberry-pi","sd-card"],"created_at":"2024-08-14T10:02:07.874Z","updated_at":"2025-04-04T17:05:15.321Z","avatar_url":"https://github.com/lucernae.png","language":"Nix","funding_links":[],"categories":["Nix"],"sub_categories":[],"readme":"# NixOS on Raspberry Pi\n\nMy personal notes on how to setup NixOS on Raspberry Pi\n\nModel:\n - Pi 3B+\n\n# Using prebuilt image available on Hydra\n\nThe latest image is on Hydra (example. You might need to change NixOS version in the following URL):\n\n[sd-image](https://hydra.nixos.org/job/nixos/release-20.09/nixos.sd_image.aarch64-linux/latest/download-by-type/file/sd-image)\n\nIf the image have extension .img.zst , then you need to uncompress it.\n\n```bash\nunzstd sd-image.img.zst\n```\n\nFlash the image to your sd card using dd. Follow the instruction in NixOS [wiki](https://nixos.wiki/wiki/NixOS_on_ARM#Installation_steps) that links to the raspberry pi original docs.\n\nWith this setup, you have a bare minimum image that you can access via HDMI and keyboard.\n\nFurther configuration are done via `/etc/nixos/configuration.nix` (the image is a NixOS).\nCreate the file and fill in your configuration.\nHere's some example from mine: [configuration.nix](configuration.nix)\n\nBuild the configuration\n\n```\nnixos-rebuild test -p test\n```\n\nThis will build the configuration but not set it as the default boot. You can try if everything works okay and then reboot. From the boot menu, choose this profile to test if everything works after reboot. If you do nothing in the boot menu, it will choose your last default profile instead of this `test` profile.\nIt is also possible to create different nixos-config file and build it accordingly to test several config:\n\n```\nnixos-rebuild test -p test-1 -I nixos-config=./test.nix\n```\n\n# Building using Github Action\n\nWe can leverage Github Action to build our image. We can reuse existing action to setup qemu-user-static and then build and deploy the image as workflow artifact. You can then download the artifact from Github, which is the zipped sd-image.img file.\n\nI already setup a workflow manual dispatch Github Action in this repo, so to build your own customized NixOS raspi image, follow this steps.\n\n1. Fork the repo so you can build your own custom image\n2. Create your build/deployment environment. \n\nFrom your repo settings page, click the Environments menu. Click New environment. Give it a name other than `default`. Define environment secrets called `CONFIGURATION_NIX`. \nThe content should be your custom `configuration.nix` file.\nThis will be imported by the `configuration.sdImage.nix`.\n\n3. Run your workflow\n\nIn the Actions page, select `nix-build-on-demand-docker` action and then click `Run workflow`. You will be given an option to specify the environment name. Fill in the name of the environment you set up in step 2. Click Run workflow. If you use `default` environment name, it will build [configuration.default.sdImage.nix](configuration.default.sdImage.nix) as the recipe.\n\n4. Wait for it to finish\n\n5. Retrieve the artifact\n\nWhen the build finish, in your action job page, there will be Artifacts panel with artifacts named `sd-image.img`. Click on it and it will download a zipped file. Extract the zipfile and it will contain the image, as `.img` or `.img.zstd` depending on your config you provided.\n\n# Building on x86/64 machine\n\nThe reason you may want to build your image yourself is because you want to store the initial config as an image.\nFor example, it may include your own initial service like SSH, or network configuration (static IP, WIFI password, etc).\n\nYou need NixOS or just Nix package manager\n\nYou need QEMU ARM if you only have Nix. \n\n## Example in Ubuntu\n\nFor example to use it in Ubuntu:\n\n*notes* for some reason, sd image build failed to build if we are using latest Linux kernel (5.4 currently). So, we need to use latest QEMU user-static that is available on debian sid (currently) or QEMU user-static version 5.x.x. Adding the repository is beyond the scope of this README and please do so if you understand that it is coming from and unstable apt repo.\n\n```bash\nsudo apt -y install qemu-user-static\n```\n\nSince we are going to run aarch64 binaries inside our x86_64 box, we need qemu-user-static to run aarch64 executable transparently.\nCheck that `binfmt_misc` now support this:\n\n```bash\nls -l /proc/sys/fs/binfmt_misc | grep aarch64\n```\n\nIf it returns something (`qemu-aarch64`), you are on the right track.\n\nAdd the following line to `/etc/nix/nix.conf`: `extra-platforms = aarch64-linux` . If the file doesn't exist, create it.\n\nCreate a base nix file for SD Card image build. Typically this contains some config for basic setup that you want to make it work right after flashing the image.\nFor example, public SSH keys, or static IP address settings, or WI-FI password, list of system packages and services, etc.\n\nThe nix file must import the SD Image packages\n\n```nix\n{ config, pkgs, lib, ... }:\n{\n\n  imports = [\n    \u003cnixos/nixos/modules/installer/cd-dvd/sd-image-aarch64.nix\u003e\n  ];\n  \n  # Do not compress the image as we want to use it straight away\n  sdImage.compressImage = false;\n\n  # The rest of user config goes here\n}\n```\n\nSee example in: [configuration.sdImage.nix](configuration.sdImage.nix)\n\nThen build the image:\n\n```\nnix-build '\u003cnixos/nixos\u003e' -A config.system.build.sdImage -I nixos-config=./configuration.sdImage.nix \\\n  --argstr system aarch64-linux \\\n  --option sandbox false\n```\n\nWhen the image finally built (normally you don't want to compress it), you can flash it to SD card like in the above instructions.\nBoot your pi and access it (via Keyboard + HDMI, or over SSH), then you need to `fix` your `/etc/nixos/configuration.nix`.\nThe nixos config that you made for building the image is for installation image, meanwhile you may have different nixos config after that.\nTypical configuration includes deleting the import lines for sd-image (So you don't rebuild image again), specifying basic fs mount (or additionally swap).\n\n## Example in NixOS\n\nIf you have NixOS, adding binfmt support is super easy.\n\nJust add the binfmt support in your `/etc/nixos/configuration.nix`\n\n```\n# add this line inside the nix function\n  boot.binfmt.emulatedSystems = [ \"aarch64-linux\" ];\n```\n\nThen, `nixos-rebuild switch` your configuration and your NixOS is ready to be used for cross-compilation.\n\nThe rest of the steps are the same with the Ubuntu example above after installing `qemu-user-static`\n\n# Building on ARM machine with Linux\n\nSame as above, but you don't need to install QEMU. You just need Nix or NixOS.\n\nThe build command:\n\n```\n# notice that we don't need to specify --argstr system aarch64-linux\nnix-build '\u003cnixos/nixos\u003e' -A config.system.build.sdImage -I nixos-config=./configuration.sdImage.nix \\\n  --option sandbox false\n```\n\n# Building using Nix Flake\n\nYou must be on a NixOS machine or Nix on Linux. The architecture won't matter.\n\nFollowing the previous guide on Building in x86_64 or ARM machine with Linux, the command is replaced\nwith Nix Flake command.\n\n```shell\nnix build .#nixosConfigurations.raspberry-pi_3.config.system.build.sdImage\n```\n\nNote, that since you can execute nix build on a remote flake, if your `configuration.nix` is already \nstored in your repo, then you can build locally against remote flake (no need to git clone).\n\n```shell\n# example using this repo as the remote flake address\nnix build github:lucernae/nixos-pi#nixosConfigurations.raspberry-pi_3.config.system.build.sdImage\n```\n\n# Building using Docker\n\nTheoritically we can also build cross-platform using Docker container. \nNormally this is used to build cross platform docker images, but we can also use it to build cross-platform in the host.\n\nYou need docker or podman installed as a prerequisite.\n\nFirst we need to register the binfmt from a docker image. We use this repository: [https://hub.docker.com/r/multiarch/qemu-user-static](https://hub.docker.com/r/multiarch/qemu-user-static).\n\n```bash\ndocker run --rm --privileged multiarch/qemu-user-static --reset -p yes\n```\n\nThe trick works like this. Normally the image above is used to register qemu-user-static interpreter inside the container. Since `/proc/sys/fs/binfmt_misc` are the same in the host and container, if the image were run using `--privileged`, then the binfmt in the host are also registered with the binaries inside the docker image. So basically the docker image serves as a convenient packaging library for qemu-user-static.\n\nAccording to the documentation, the `-p yes` flag tells the image to register the binfmt and persists it even if the container exits. So the interpreter are also available in the host kernel. However you can't check the interpreter version directly in the host, since the binaries don't exists in the host (but in the image above). To check the version, the author uses the convention like this:\n\n```bash\n# supply the platform as image tag, e.g. aarch64\ndocker run --rm --privileged multiarch/qemu-user-static:aarch64 /usr/bin/qemu-aarch64-static --version\n```\n\nNow your kernel can execute aarch64 binaries and you can cross-compile. There rest of the steps are the same.\n\n# Reference\n\n- [NixOS on ARM installation notes](https://nixos.wiki/wiki/NixOS_on_ARM#Installation)\n- [NixOS Pi 3 installation notes](https://nixos.wiki/wiki/NixOS_on_ARM/Raspberry_Pi_3#Board-specific_installation_notes)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucernae%2Fnixos-pi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flucernae%2Fnixos-pi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flucernae%2Fnixos-pi/lists"}