install-nix-action: putting a working Nix on a GitHub Actions runner
Installs Nix on GitHub Actions for the supported platforms: Linux and macOS.
At a glance
- What is it?
- install-nix-action is a Cachix action that installs Nix on GitHub Actions runners for Linux and macOS, with CI tuned defaults such as flakes enabled, trusted users and KVM turned on, so a workflow can run nix build without hand-writing an installer step. It suits a repository moving to Nix, and it does not cover Windows runners.
- Who is it for?
- install-nix-action fits a repository that wants to build with Nix in CI without writing the installer and the configuration yourself, and it does not fit a team that needs Windows runners, since the supported platforms are Linux and macOS.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One step in a workflow, replacing a page of shell
install-nix-action installs Nix on GitHub Actions runners for Linux and macOS. The repository is small: the top level holds action.yml, the install-nix.sh script it wraps, a tests directory with a test workflow, a RELEASE.md, a README and the LICENSE, and the primary language is recorded as Shell.
The usage is a single step in a workflow file, and the README's first example is a complete job. You create .github/workflows/test.yml in your repo with the following contents.
name: "Test"
on:
pull_request:
push:
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstable
- run: nix-buildThe step order matters and is the whole point. The action runs after the checkout, because it is the checkout that provides the repository the subsequent nix-build has to build, and the nix_path input sets the channel the build resolves against.
The features list gives the practical reasons a team reaches for this rather than a hand written install step. Quick installation, around four seconds on Linux and around twenty seconds on macOS. Multi-user installation with sandboxing enabled by default on Linux. Support for self-hosted GitHub runners. And the ability to specify the Nix installation URL via install_url, where the oldest supported Nix version is 2.3.5.
The action is Apache-2.0 licensed, the default branch is master, and the last push was on 2026-10-14, the same day as the v31.11.2 release.
The seven inputs, and the one that gets you rate limits
The inputs table is the reference for the action, and one of the entries is worth reading twice.
install_url is the URL to install Nix from, useful for testing non-stable releases or pinning a specific Nix version, and it defaults to an empty string. install_options passes additional flags to the Nix installer script. extra_nix_config appends additional configuration to /etc/nix/nix.conf. nix_path sets the value of the NIX_PATH environment variable, for example nixpkgs=channel:nixos-unstable.
github_access_token is a GitHub token for Nix to use when pulling from GitHub repositories, and the description says it helps work around rate limit issues. It has no effect when access-tokens is specified in extra_nix_config, and it defaults to $GITHUB_TOKEN if available.
The last two inputs are the interesting ones for a CI setup. set_as_trusted_user adds the current user to the trusted-users list, and it defaults to true. enable_kvm enables KVM for hardware-accelerated virtualization on Linux, and it also defaults to true.
Both defaults are the right call for a runner, and both are worth understanding rather than accepting silently. A trusted user is one permitted to change the Nix configuration and to install packages, and on a shared CI runner the account running the workflow is the account that has to be trusted for the store to be writable. KVM being on by default is what makes NixOS test suites and virtual machine builds possible, and the feature list calls out running VMs and NixOS tests with full hardware acceleration.
If you would rather not have the runner user trusted, or you are on a host where KVM is not available, both are one input away.
The defaults that differ from a laptop install
There is a whole section devoted to this, titled Differences from the default Nix installer, and it is the most consequential part of the documentation for anyone comparing this action with installing Nix by hand.
The section says some settings have been optimised for use in CI environments, and lists the nix.conf settings you can override with extra_nix_config.
The experimental flakes and nix-command features are enabled by default, and you disable them by overriding experimental-features in extra_nix_config. This is why the workflow in the README can run nix flake check without any further setup, and it is the single behaviour that differs most from a normal installation.
max-jobs is set to auto, show-trace is set to true, always-allow-substitutes is set to true, and $USER is added to trusted-users. $GITHUB_TOKEN is added to access_tokens if no other github_access_token is provided. On macOS, ssl-cert-file is set to /etc/ssl/cert.pem.
Beyond nix.conf there are two more differences. KVM is enabled on Linux if available, disabled by setting enable_kvm: false. $TMPDIR is set to $RUNNER_TEMP if empty.
Two of these deserve a comment. show-trace being on by default means a failing build prints the full Nix evaluation trace, which is what you want in CI and is why a CI log is often longer than the equivalent local one. And $GITHUB_TOKEN being injected into access_tokens is a convenience that also means a workflow has the token in the Nix configuration by default, which is worth knowing if you audit what a build can reach.
Flakes, channels, and the fact that no channel is set up for you
The FAQ answers the question that trips people up first, which is how to add a nixpkgs channel. The answer is that this action doesn't set up any channels by default, and you use nix_path to configure optional channels by picking a channel or pinning nixpkgs to a specific commit.
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=channel:nixos-unstableThe same example appears in the primary usage block, with the newer nix build and nix flake check commands in place of nix-build, and a github_access_token supplied from secrets.GITHUB_TOKEN. The two variants together suggest the intended progression, from the legacy nix-build path with an explicit channel to the flakes path with a token.
The README also links a tutorial on pinning on nix.dev for the case where you want a specific commit rather than a channel, and a link to the channel status page for picking a channel. That is the right answer for a repository whose builds must be reproducible, since a channel name is a moving target and a commit is not.
If your workflow instead wants the old channel-style environment, there is a documented way to install packages from a specified nix_path.
nix-env -i mypackage -f '<nixpkgs>'And if you want to know which nixpkgs you actually got, the FAQ shows how to print it.
- name: Print nixpkgs version
run: nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'Binary caches, and the one thing that will bite a multi-user setup
The FAQ covers adding a binary cache, and it splits the answer by whether you use Cachix's own action.
If the binary cache you want to add is hosted on Cachix and you are using cachix-action, you use their extraPullNames input like this.
- uses: cachix/cachix-action@v31
with:
name: mycache
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
extraPullNames: nix-communityOtherwise, you can add any binary cache to nix.conf using install-nix-action's own extra_nix_config input, and the example shows the two keys you need, trusted-public-keys and substituters.
- uses: cachix/install-nix-action@v31
with:
extra_nix_config: |
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
substituters = https://hydra.iohk.io https://cache.nixos.org/This is the part of the action that matters most for build times, since a binary cache turns a from-source build into a download. The feature list points at it as well, noting the action can be paired with a binary cache from cachix-action to speed up re-builds and share binaries across your team.
The last FAQ entry is the one to read before assuming secrets will work. In multi-user mode, Nix commands that operate on the Nix store are forwarded to a privileged daemon, and that daemon runs in a separate context from your GitHub Actions workflow and cannot access the workflow's environment variables. Any secrets or credentials defined in the workflow environment will not be available to Nix operations that require store access. The README begins describing two ways to pass AWS credentials to the daemon, and the text is cut off there, so the exact mechanism is not in the documentation this repository provides.
nix develop, pure mode, and why your environment variables disappear
Two FAQ entries cover the part of Nix that surprises people arriving from CI: pure mode.
The first explains how to configure steps to use the flake's development environment, and it recommends configuring the shell of a step to use nix develop. The example shows a two step approach, with the devShell pre-built separately.
# (optional) pre-build the shell separately to avoid skewing the run time of the next
# step and have clear point of failure should the shell fail to build
- name: Pre-build devShell
run: nix build --no-link .#devShells.$(nix eval --impure --raw --expr 'builtins.currentSystem').default
- name: Run a command with nix develop
shell: 'nix develop -c bash -e {0}'
run: echo "hello, pure world!"The comment in the example is the useful part. Building the shell separately gives a clear point of failure, and it stops the shell build time from being folded into the measured runtime of the next step, which matters when a workflow reports timings.
The second entry explains that Nix runs commands in a restricted environment by default, called pure mode, and that in pure mode environment variables are not passed through to improve the reproducibility of the shell. The fix is the --keep or -k flag.
- name: Run a command with nix develop
run: nix develop --ignore-environment --keep MY_ENV_VAR --command echo $MY_ENV_VAR
env:
MY_ENV_VAR: "hello world"Or you can disable pure mode entirely with the --impure flag.
nix develop --impureFor a CI workflow the trade is between reproducibility and convenience. Pure mode means a build does not accidentally depend on a variable that happened to be set on the runner, and the --keep flag lets you be explicit about the ones that matter, which is usually the better answer than switching purity off for the whole job.
Editorial conclusion
install-nix-action fits a repository that wants to build with Nix in CI without writing the installer and the configuration yourself, and it does not fit a team that needs Windows runners, since the supported platforms are Linux and macOS. Before adopting it, read the Differences from the default Nix installer section, because the action enables experimental features and adds the runner user to trusted-users by default, and both are overrides you may need to change, and note that the action does not set up any channels, so nix_path has to be configured explicitly if your build expects one.
Frequently asked questions
How do I install Nix on a GitHub Actions runner?
Add cachix/install-nix-action@v31 as a step after actions/checkout@v5 in your workflow file, then run nix build or nix-build in a later step. The action supports Linux and macOS runners and installs Nix in about four seconds on Linux and about twenty seconds on macOS.
Does install-nix-action set up a nixpkgs channel?
No. The action doesn't set up any channels by default. You configure optional channels with the nix_path input, either by picking a channel or by pinning nixpkgs to a specific commit.
How do I run NixOS tests on a Linux runner with install-nix-action?
KVM is enabled on Linux if available, and the README gives an example that also sets the system-features for nixos-test, benchmark, big-parallel and kvm through extra_nix_config. You can turn KVM off by setting enable_kvm: false.
Why are my environment variables missing inside nix develop in a workflow?
Nix runs commands in a restricted environment by default, called pure mode, and in pure mode environment variables are not passed through. Use the --keep or -k flag to keep specific variables, or the --impure flag to disable pure mode entirely.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cachix-install-nix-action)Was this useful?