harmonia
harmonia copied to clipboard
Nix binary cache implemented in rust using libnix-store (maintainer: @Mic92)
harmonia
Harmonia is a binary cache for nix that serves your /nix/store as a binary cache over http. It's written in Rust for speed.
Features
- http-ranges support for nar file streaming
- streaming build logs
- .ls file streaming
- Note: doesn't contain
narOffset
in json response but isn't needed fornix-index
- Note: doesn't contain
- Add
/serve/<narhash>/
endpoint to allow serving the content of package. Also discovers index.html to allow serving websites directly from the nix store.
Configuration for public binary cache on NixOS
Since NixOS 23.05, there is a module for harmonia in nixpkgs. The following example set's up harmonia as a public binary cache using nginx as a frontend webserver with https encryption and zstd for compression:
{ config, pkgs, ... }: {
services.harmonia.enable = true;
# FIXME: generate a public/private key pair like this:
# $ nix-store --generate-binary-cache-key cache.yourdomain.tld-1 /var/lib/secrets/harmonia.secret /var/lib/secrets/harmonia.pub
services.harmonia.signKeyPath = "/var/lib/secrets/harmonia.secret";
# Example using sops-nix to store the signing key
#services.harmonia.signKeyPath = config.sops.secrets.harmonia-key.path;
#sops.secrets.harmonia-key = { };
# optional if you use allowed-users in other places
#nix.settings.allowed-users = [ "harmonia" ];
networking.firewall.allowedTCPPorts = [ 443 80 ];
# FIXME: replace this with your own email
security.acme.defaults.email = "[email protected]";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
package = pkgs.nginxStable.override {
modules = [ pkgs.nginxModules.zstd ];
};
recommendedTlsSettings = true;
recommendedZstdSettings = true;
# FIXME: replace "cache.yourdomain.tld" with your own domain.
virtualHosts."cache.yourdomain.tld" = {
enableACME = true;
forceSSL = true;
locations."/".extraConfig = ''
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_redirect http:// https://;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
zstd on;
zstd_types application/x-nix-archive;
'';
};
};
}
You can use the binary cache on a different machine using the following NixOS configuration:
{
nix.settings = {
substituters = [ "https://cache.yourdomain.tld" ];
# FIXME replace the key with the content of /var/lib/secrets/harmonia.pub
trusted-public-keys = [ "cache.yourdomain.tld-1:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" ];
};
}
Configuration format
Configuration is done via a toml
file.
Hint: You don't need to interface with the configuration directly in case you are using the NixOS module.
The location of the configuration file should be passed as env var CONFIG_FILE
. If no config file is passed the
following default values will be used:
# default ip:hostname to bind to
bind = "[::]:5000"
# Sets number of workers to start in the webserver
workers = 4
# Sets the per-worker maximum number of concurrent connections.
max_connection_rate = 256
# binary cache priority that is advertised in /nix-cache-info
priority = 30
Per default we wont sign any narinfo because we don't have a secret key, to
enable this feature enable it by providing a path to a private key generated by
nix-store --generate-binary-cache-key cache.example.com-1 /etc/nix/cache.secret /etc/nix/cache.pub
# nix binary cache signing key
sign_key_path = "/run/secrets/cache.secret"
harmonia will fallback to the SIGN_KEY_PATH
environment if sign_key_path
is not set in configuration.
Logging can be configured with
env_logger. The default value
is info,actix_web=debug
. To only log errors use the following
RUST_LOG=error
and to only disable access logging, use
RUST_LOG=info,actix_web::middleware=error
Build
Whole application
nix build -L
Get a development environment:
nix develop
Run tests
nix flake check -L