Aloja tu propio servidor de caché binaria de Nix
Introducción
La caché binaria de Nix es una implementación del Nix Store que almacena datos en un servidor remoto en lugar de localmente, lo que facilita compartir cachés binarias entre varias máquinas.
El servidor oficial de caché binaria de Nix solo proporciona binarios construidos con parámetros estándar. Si has personalizado los parámetros de compilación o estás usando paquetes fuera de Nixpkgs, Nix no encontrará la caché binaria correspondiente, lo que provoca compilaciones locales.
Depender únicamente de tu Nix Store local /nix/store puede ser engorroso, ya que tendrías que recompilar todos tus paquetes personalizados en cada máquina, lo cual puede llevar tiempo y consumir mucha memoria. Esta situación empeora en plataformas de menor rendimiento como Raspberry Pi.
Este documento te mostrará cómo configurar tu propio servidor de caché binaria de Nix usando un servicio S3 (como MinIO) para compartir resultados de compilación entre máquinas y resolver los problemas anteriores.
Requisitos previous
- Un host con NixOS
- Un servidor MinIO desplegado
- Si no lo tienes, puedes seguir la guía oficial de despliegue de MinIO.
- El servidor MinIO necesita un certificado digital TLS válido, que puede ser público o privado. Este ejemplo usará
https://minio.homelab.localcon un certificado privado. - Instalar
minio-client
Generar una contraseña
nix run nixpkgs#pwgen -- -c -n -y -s -B 32 1
# => oenu1Yuch3rohz2ahveid0koo4giechoConfigurar el cliente MinIO
Instala el cliente de línea de comandos de MinIO mc.
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
minio-client # alternativas para los comandos ls, cp, mkdir, diff y rsync para sistemas de archivos y almacenamiento de objetos
];
}Crea ~/.mc/config.json con el siguiente contenido (reemplaza los parámetros clave por los tuyos):
{
"version": "10",
"aliases": {
"s3": {
"url": "https://s3.homelab.local",
"accessKey": "minio",
"secretKey": "oenu1Yuch3rohz2ahveid0koo4giecho",
"api": "s3v4",
"path": "auto"
}
}
}Como Nix interactuará directamente con el bucket S3, necesitamos configurar credenciales S3 para todas las máquinas que requieran acceso a la caché binaria de Nix.
Crea ~/.aws/credentials con el siguiente contenido (reemplaza <nixbuildersecret> por la contraseña generada por pwgen).
[nixbuilder]
aws_access_key_id=nixbuilder
aws_secret_access_key=<nixbuildersecret>Configurar el bucket S3 como caché binaria
Crea el bucket nix-cache usando el cliente de MinIO:
mc mb s3/nix-cacheCrea el usuario nixbuilder para MinIO y asígnale una contraseña:
mc admin user add s3 nixbuilder <PASSWORD>Crea un archivo llamado nix-cache-write.json en el directorio de trabajo actual con el siguiente contenido:
{
"Id": "AuthenticatedWrite",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AuthenticatedWrite",
"Action": [
"s3:AbortMultipartUpload",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListMultipartUploadParts",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::nix-cache", "arn:aws:s3:::nix-cache/*"],
"Principal": "nixbuilder"
}
]
}Ahora crea una política para subir archivos a S3 usando el archivo nix-cache-write.json:
mc admin policy create s3 nix-cache-write nix-cache-write.jsonAsocia la política S3 que acabamos de crear con el usuario nixbuilder:
mc admin policy attach s3 nix-cache-write -user nixbuilderPermite que usuarios anónimos descarguen archivos sin autenticación, para que todos los servidores Nix puedan obtener datos directamente desde esta caché S3:
mc anonymous set download s3/nix-cachePor último, añade el archivo nix-cache-info al directorio raíz del bucket S3, ya que Nix Requiere este archivo para registrar cierta información relacionada con la caché binaria:
cat > nix-cache-info <<EOF
StoreDir: /nix/store
WantMassQuery: 1
Priority: 40
EOF
# Copia `nix-cache-info` al bucket S3
mc cp ./nix-cache-info s3/nix-cache/nix-cache-infoGenerar par de claves de firma
Como se mencionó antes, la caché binaria de Nix usa un mecanismo de firma con clave pública para verificar el origen e integridad de los datos, así que necesitamos generar un par de claves para que nuestra máquina de compilación Nix firme la caché binaria. El nombre de la clave es arbitrario, pero los desarrolladores de NixOS recomiendan encarecidamente usar el dominio de la caché seguido de un entero, para que si la clave necesita revocarse o regenerarse, puedas simplemente incrementar el entero al final.
nix key generate-secret --key-name s3.homelab.local-1 > ~/.config/nix/secret.key
nix key convert-secret-to-public < ~/.config/nix/secret.key > ~/.config/nix/public.key
cat ~/.config/nix/public.key
# => s3.homelab.local-1:m0J/oDlLEuG6ezc6MzmpLCN2MYjssO3NMIlr9JdxkTs=Usar la caché binaria S3 en flake.nix
Añade lo siguiente a tu configuration.nix o a cualquier módulo personalizado de NixOS:
{
nix = {
settings = {
# el substituter se añadirá a los substituters predeterminados al buscar paquetes
extra-substituters = [
"https://s3.homelab.local/nix-cache/"
];
extra-trusted-public-keys = [
"s3.homelab.local-1:m0J/oDlLEuG6ezc6MzmpLCN2MYjssO3NMIlr9JdxkTs="
];
};
};
}Reconstruye el sistema para empezar a usar nuestra nueva caché binaria S3:
sudo nixos-rebuild switch --upgrade --flake .#<HOST>Enviar rutas del store a la caché binaria
Firma algunas rutas en el store local.
nix store sign --recursive --key-file ~/.config/nix/secret.key /run/current-systemCopia esas rutas a la caché:
nix copy --to 's3://nix-cache?profile=nixbuilder&endpoint=s3.homelab.local' /run/current-systemAgregar una política automática de expiración de objetos
mc ilm rule add s3/nix-cache --expire-days "DAYS"
# Por ejemplo: mc ilm rule add s3/nix-cache --expire-days "7"Esto establecerá una política de expiración para los objetos en el bucket S3, asegurando que se eliminen automáticamente después de un número determinado de días.
Esto es útil para mantener manejable el tamaño de la caché y garantizar que los binarios obsoletos no se almacenen indefinidamente.