NixCI Cache

NixCI automatically uses a specialised NixCI Cache for all builds.

You can benefit from this cache on your own machine as well.

Authentication

Get Netrc file

In order to use the NixCI cache, you need to use a netrc file to authenticate using a user auth token.

Click here to generate a user auth token and netrc file and put it at ~/.netrc.

Once you have your netrc file, try it out using curl :

curl https://cache.nix-ci.com/nix-cache-info

By default, curl does not use the netrc file, so you should see:

Request rejected

Access to this NixCI cache requires authentication.
You'll need to add your credentials in your netrc file.

If you are trying to use this cache as a substituter,
make sure you have set netrc-file in your nix.conf.

If you are running curl yourself,
make sure you have a ~/.netrc file and use curl --netrc.

Now, try again with --netrc :

curl --netrc https://cache.nix-ci.com/nix-cache-info

You should see:

StoreDir: /nix/store
WantMassQuery: 1
Priority: 0
AuthenticationRequired: 'yes'
Authenticated: <your user id>
ReadAllowed: <your repositories>
WriteAllowed: <your user id>

If this works, you have succesfully authenticated with the NixCI cache.

Configure Netrc file

Next, we need to tell Nix to use this netrc file.

On NixOS set this and rebuild:

nix.settings.netrc-file = "/home/user/.netrc"

Without NixOS, in your /etc/nix/nix.conf and /home/user/.config/nix/nix.conf :

netrc-file = /home/user/.netrc

To try it out, we can copy something to the cache:

nix copy github:nixos/nixpkgs#hello --to https://cache.nix-ci.com
If this succeeds, you have succesfully configured Nix to authenticate with the cache.

Pushing to the cache manually

You can push to the cache using nix copy :

nix copy ./result --to  https://cache.nix-ci.com
or
nix copy .#yourPackage --to  https://cache.nix-ci.com
NixCI works out who may read what you push. The owners and access section below explains which owners you and your builds can reach.

Using the cache yourself

All builds on NixCI automatically use the cache already, but you yourself can also use it locally.

Configure the substituter

On NixOS, set this and rebuild:

nix.settings.substituters = ["https://cache.nix-ci.com"];

Trust the signing key

NixCI workers use sign everything they build so you can require a signature of theirs to trust the build outputs.

On NixOS, set this and rebuild:

nix.settings.trusted-public-keys = ["nix-ci:g3xV5BDTLtIBZr/A00IU1x0EtKKlb7YLgBN2SgYgM6A="];

Alternatively you can trust unsigned builds, but that is not recommended and therefore not documented here.

You should see the key listed when you run this command:

nix config show | grep trusted-public-keys

You can then try to pull from the cache:

nix copy --from https://cache.nix-ci.com $(nix path-info github:nixos/nixpkgs#hello)

You can also set these in a flake to have per-flake caching instead:

nixConfig = {
  extra-substituters = "https://cache.nix-ci.com";
  extra-trusted-public-keys = "nix-ci:g3xV5BDTLtIBZr/A00IU1x0EtKKlb7YLgBN2SgYgM6A=";
};

Understanding Owners and Access

Everything in the cache is stored under an owner: a namespace that decides who may read and write it.

An owner is one of:

  • a user's own private namespace, written like user:3f9c1e7a-1b2c-4d5e-6f70-8a9b0c1d2e3f
  • a forge account, which covers every repository under it:
    • github:acme for GitHub
    • gitlab:mygroup for GitLab
    • codeberg:me for Codeberg
  • a specific repository, shared by everyone who can access it:
    • github:acme:widget for GitHub
    • gitlab:mygroup:myproject for GitLab
    • codeberg:me:myrepo for Codeberg

NixCI works out which owners your auth token may reach, and re-checks it on every request.

Workers

A worker building the GitHub repository acme/widget writes to github:acme:widget and can read from:

  • that repository, github:acme:widget
  • everything else under its owner, github:acme
  • the namespace of the user that owns it, like user:7b2e5d1c-3a4b-4c5d-6e7f-8091a2b3c4d5

Users

You can write to one owner only, your own private namespace, so anything you push stays private to you:

  • user:3f9c1e7a-1b2c-4d5e-6f70-8a9b0c1d2e3f

You can read from:

  • your own private namespace, like user:3f9c1e7a-1b2c-4d5e-6f70-8a9b0c1d2e3f
  • your own account's namespace, like github:you
  • every repository you have access to, like github:acme:widget