OCI Registry As Nix Cache.
Use an OCI registry (typically, ghcr.io) to distribute binary caches of your Nix packages!
-
Tags, image manifests, and layers created by oranc are so different from other typical OCI repositories. So I don't know if it is an abuse of OCI registries. Pushing to ghcr.io may violate the terms of service of GitHub.
-
Repository schema of oranc is still unstable.
Tag encoding has been updated to support CA realisations. To use old pushed cache, please use the
--fallback-encodings base32-dnssecoption.$ oranc tag encode "realisations/sha256:67890e0958e5d1a2944a3389151472a9acde025c7812f68381a7eef0d82152d1!libgcc.doi" realisations_L_sha256_W_67890e0958e5d1a2944a3389151472a9acde025c7812f68381a7eef0d82152d1_x_libgcc.doi $ oranc tag encode "realisations/sha256:67890e0958e5d1a2944a3389151472a9acde025c7812f68381a7eef0d82152d1!libgcc.doi" \ --fallbacks --fallback-encodings base32-dnssec realisations_L_sha256_W_67890e0958e5d1a2944a3389151472a9acde025c7812f68381a7eef0d82152d1_x_libgcc.doi e9im2r39edgn8qbfdppiusr8c4p3adhq6orjge9gcko3id9ockqm8cb168sj8d316cpjge9h6koj8dpic4sm2or4cko34db36ss32cj66os36e1hc4rmapb661i3gchh6kp68c91dhkm4pr3ccn68rr9
The
base32-dnssecencoding for realisation is too long to fit into an OCI reference tag.
There are two different ways to push cache to OCI registry using oranc.
- Direct push using
oranc push(faster but has some limitations). - Push using
nix copywith oranc server.
-
Prepare your signing keys.
$ nix key generate-secret --key-name {KEY_NAME} > {PRIVATE_KEY_FILE} $ cat {PRIVATE_KEY_FILE} | nix key convert-secret-to-public {PUBLIC_KEY}
-
Set your credentials.
export ORANC_USERNAME={YOUR_OCI_REGISTRY_USERNAME} export ORANC_PASSWORD={YOUR_OCI_REGISTRY_PASSWORD} export ORANC_SIGNING_KEY={YOUR_NIX_SIGNING_KEY}
-
Initialize your OCI registry.
oranc push --registry {OCI_REGISTRY} --repository {OCI_REPOSITORY} initializeMake the repository public, otherwise, caching will not work.
-
Build something.
nix build
-
Push to your OCI registry.
# you need to have write permission to `/nix/var/nix/db` # or pass the argument `--allow-immutable-db` # see the Limitations section echo ./result | oranc push --registry {OCI_REGISTRY} --repository {OCI_REPOSITORY}
orancwill sign the NAR archive on the fly usingORANC_SIGNING_KEY.Note that:
- Only unsigned paths will be pushed, if you manually signed store paths, use the argument
--already-signedto push them. - Currently,
orancwill not sign local paths, run... | xargs nix store sign --recursive --key-file {YOUR_KEY_FILE}to sign paths locally.
Run
oranc push --helpfor more options. - Only unsigned paths will be pushed, if you manually signed store paths, use the argument
-
Host a oranc server, or try oranc.li7g.com. It's better to self-host an instance. If you do so, please replace all
oranc.li7g.combelow with your instance.oranc server --listen "{LISTEN_ADDRESS}:{LISTEN_PORT}" -
Set your credentials.
export ORANC_USERNAME={YOUR_OCI_REGISTRY_USERNAME} export ORANC_PASSWORD={YOUR_OCI_REGISTRY_PASSWORD} export AWS_ACCESS_KEY_ID=$(echo -n "$ORANC_USERNAME:$ORANC_PASSWORD" | base64 --wrap 0) export AWS_SECRET_ACCESS_KEY="_"
-
Build something.
nix build
-
Push to your OCI registry.
nix copy --to "s3://{OCI_REPOSITORY_PART2}?endpoint=https://oranc.li7g.com/{OCI_REGISTRY}/{OCI_REPOSITORY_PART1}" ./resultCache will be pushed to
https://{OCI_REGISTRY}/{OCI_REPOSITORY_PART1}/{OCI_REPOSITORY_PART2}.
-
oranc pushreads the SQLite database/nix/var/nix/db/db.sqlite. The directory containing the database,/nix/var/nix/db, is typically owned by root. To open the database,orancmust have permission to create WAL files under the directory.To avoid requiring root permission to do
oranc push, iforanc pushdoes not able to create files under/nix/var/nix/db/db.sqliteand the argument--allow-immutable-dbis passed, it will open the database inimmutable=1mode, if another process writes to the database,oranc push --allow-immutable-dbmay fail. -
oranc pushdoes not support pushing content-addressed realisations.
Try oranc.li7g.com. It's better to self-host an instance. If you do so, please replace all oranc.li7g.com below with your instance.
Add settings to nix.conf:
substituters = https://oranc.li7g.com/{OCI_REGISTRY}/{OCI_REPOSITORY}
trusted-public-keys = {PUBLIC_KEY}
or use NixOS configuration:
{ ... }:
{
nix.settings = {
substituters = [ "https://oranc.li7g.com/{OCI_REGISTRY}/{OCI_REPOSITORY}" ];
trusted-public-keys = [ "{PUBLIC_KEY}" ];
};
}If your OCI registry requires authentication, HTTP basic authentication is supported:
- Add username and password to the substituter URL:
https://{ORANC_USERNAME}:{ORANC_PASSWORD}@oranc.li7g.com/{OCI_REGISTRY}/{OCI_REPOSITORY}. - Or use a netrc file https://nixos.wiki/wiki/Enterprise.
Your credential will be sent to the oranc server. If you don't trust my instance, please host your own instance.
Simply run,
oranc server --listen "{LISTEN_ADDRESS}:{LISTEN_PORT}"Run oranc server --help for more options.
A NixOS module (github:linyinfeng/oranc#nixosModules.oranc) and a nixpkgs overlay (github:linyinfeng/oranc#overlays.oranc) are provided.
The OCI references used by ghcr.io follow the format {owner}/{package}, which contains exactly one slash (i.e., two path components). However, general OCI references may include any number of slashes.
By default, oranc server is designed to work with ghcr.io out of the box, so it only accepts references that contain a single slash (two components). You can change this behavior with the --repository-parts <NUM> option. This option defaults to 2, meaning the server expects exactly two path components—{owner} and {package}—separated by one slash.
[ ] Improve push performance of oranc server.