HTTP 바이너리 캐시 설정하기#

Author:

Jacek Galowicz @tfc

Editor:

Valentin Gagarin @fricklerhandwerk

바이너리 캐시는 미리 빌드된 Nix 스토어 객체를 저장하고 네트워크를 통해 다른 머신에 제공합니다. Nix 스토어가 있는 머신이라면 어떤 머신이든 다른 머신을 위한 바이너리 캐시가 될 수 있습니다.

소개#

이 튜토리얼에서는 NixOS 머신의 스토어 객체를 HTTP 또는 HTTPS로 제공하는 Nix 바이너리 캐시를 설정합니다.

무엇을 배우게 됩니까?#

다음 방법을 배웁니다:

  • 캐시용 서명 키 설정하기

  • 캐시를 제공하는 NixOS 머신에서 필요한 서비스 활성화하기

  • 설정이 의도한 대로 동작하는지 확인하기

무엇이 필요합니까?#

로컬 네트워크의 캐시에 대해서는 다음을 가정합니다:

  • 호스트 이름은 cache입니다(자신의 호스트 이름이나 IP 주소로 바꾸십시오)

  • 호스트는 80번 포트에서 HTTP로 스토어 객체를 제공합니다(기본값입니다)

공개적으로 접근 가능한 캐시에 대해서는 다음을 가정합니다:

  • 도메인 이름은 cache.example.com입니다(자신의 도메인 이름으로 바꾸십시오)

  • 호스트는 443번 포트에서 HTTPS로 스토어 객체를 제공합니다(기본값입니다)

얼마나 걸립니까?#

  • 25분

서비스 설정하기#

캐시를 호스팅하는 NixOS 머신을 위해 binary-cache.nix에 새 설정 모듈을 만드십시오:

{ config, ... }:

{
  services.nix-serve = {
    enable = true;
    secretKeyFile = "/var/secrets/cache-private-key.pem";
  };

  services.nginx = {
    enable = true;
    recommendedProxySettings = true;
    virtualHosts.cache = {
      locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
    };
  };

  networking.firewall.allowedTCPPorts = [
    config.services.nginx.defaultHTTPListenPort
  ];
}

services.nix-serve 아래의 옵션은 바이너리 캐시 서비스를 설정합니다.

nix-serve는 IPv6나 SSL/HTTPS를 지원하지 않습니다. services.nginx 옵션은 호스트 이름 cache로 들어오는 요청을 처리할 프록시를 설정하는 데 사용되며, 이 프록시는 IPv6를 지원합니다.

중요

이 튜토리얼의 끝에 선택 사항인 HTTPS 섹션이 있습니다.

새 NixOS 모듈을 기존 머신 설정에 추가하십시오:

{ config, ... }:

{
  imports = [
    ./binary-cache.nix
  ];

  # ...
}

로컬 머신에서 새 설정을 배포하십시오:

nixos-rebuild switch --no-flake --target-host root@cache

참고

아직 비밀 키 파일이 없으므로 바이너리 캐시 데몬이 오류를 보고합니다.

서명 키 쌍 생성하기#

캐시에 있는 스토어 객체가 진본임을 보장하려면 개인 키와 공개 키 한 쌍이 필요합니다.

바이너리 캐시용 키 쌍을 생성하려면 예시 호스트 이름 cache.example.com을 여러분의 호스트 이름으로 바꾸십시오:

nix-store --generate-binary-cache-key cache.example.com cache-private-key.pem cache-public-key.pem

cache-private-key.pem은 바이너리 캐시 데몬이 바이너리를 제공할 때 서명하는 데 사용됩니다. 캐시를 호스팅하는 머신에서 services.nix-serve.secretKeyFile에 설정된 위치로 이 파일을 복사하십시오:

scp cache-private-key.pem root@cache:/var/secrets/cache-private-key.pem

지금까지 바이너리 캐시 데몬은 비밀 키 파일이 없어서 재시작을 반복하고 있었습니다. 이제 올바르게 작동하는지 확인하십시오:

ssh root@cache systemctl status nix-serve.service

중요

사용자 지정 바이너리 캐시를 사용하도록 Nix 설정하기 — 로컬 머신에서 cache-public-key.pem을 사용하십시오.

가용성 테스트하기#

다음 단계에서는 모든 것이 올바르게 설정되었는지 확인하며, 문제를 파악하는 데 도움이 될 수 있습니다.

일반 가용성 확인하기#

캐시에 쿼리를 보내 바이너리 캐시, 리버스 프록시, 방화벽 규칙이 의도한 대로 작동하는지 테스트하십시오:

$ curl http://cache/nix-cache-info
StoreDir: /nix/store
WantMassQuery: 1
Priority: 30

스토어 객체 서명 확인하기#

스토어 객체가 올바르게 서명되었는지 테스트하려면 예시 derivation의 메타데이터를 살펴보십시오. 바이너리 캐시 호스트에서 hello 패키지를 빌드하고 캐시에서 .narinfo 파일을 가져오십시오:

$ hash=$(nix-build '<nixpkgs>' -A pkgs.hello | awk -F '/' '{print $4}' | awk -F '-' '{print $1}')
$ curl "http://cache/$hash.narinfo" | grep "Sig: "
...
Sig: cache.example.org:GyBFzocLAeLEFd0hr2noK84VzPUw0ArCNYEnrm1YXakdsC5FkO2Bkj2JH8Xjou+wxeXMjFKa0YP2AML7nBWsAg==

출력에 Sig:로 시작하는 줄이 포함되어 있고 그 줄에 여러분이 생성한 공개 키가 표시되는지 확인하십시오.

HTTPS로 바이너리 캐시 제공하기#

바이너리 캐시에 공개적으로 접근할 수 있다면 Let’s Encrypt SSL 인증서로 HTTPS를 강제할 수 있습니다. 다음과 같이 binary-cache.nix를 편집하고, 예시 URL과 메일 주소를 반드시 여러분의 것으로 바꾸십시오:

   services.nginx = {
     enable = true;
     recommendedProxySettings = true;
-    virtualHosts.cache = {
+    virtualHosts."cache.example.com" = {
+      enableACME = true;
+      forceSSL = true;
       locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
     };
   };

+   security.acme = {
+     acceptTerms = true;
+     certs = {
+       "cache.example.com".email = "you@example.com";
+     };
+   };

   networking.firewall.allowedTCPPorts = [
     config.services.nginx.defaultHTTPListenPort
+    config.services.nginx.defaultSSLListenPort
   ];

시스템을 다시 빌드하여 이 변경 사항을 배포하십시오:

nixos-rebuild switch --no-flake --target-host root@cache.example.com

다음 단계#

바이너리 캐시가 이미 원격 빌드 머신이라면 해당 Nix 스토어의 모든 스토어 객체를 제공합니다.

저장 공간을 절약하려면 다음 NixOS 설정 속성을 참고하십시오:

  • nix.gc: 자동 가비지 컬렉션 옵션

  • nix.optimise: 주기적인 Nix 스토어 최적화 옵션

대안#

  • nix-serve-ng: Haskell로 작성된 nix-serve의 드롭인 대체품

  • SSH 스토어, 실험적 SSH 스토어, S3 바이너리 캐시 스토어도 캐시를 제공하는 데 사용할 수 있습니다. S3 호환 스토리지를 제공하는 상용 업체는 많이 있습니다. 예를 들면 다음과 같습니다.

    • Amazon S3

    • Tigris

    • Cloudflare R2

  • attic: S3 호환 스토리지 제공 업체를 기반으로 하는 Nix 바이너리 캐시 서버

  • Cachix: 서비스형 Nix 바이너리 캐시

참고 자료#