Nix 플레이크
Nix 코드를 참조하고 공유하기 위한 시스템입니다.
We recommend starting with the Nix quick start and consulting concept docs primarily for clarification. Feel free to click x to the right to disable this notification on all concept docs.
Nix 플레이크는 현재 Nix에서 실험적인 기능이며 현재 플레이크를 공식화하기 위한 구체적인 일정은 없습니다. 플레이크 관련 사용자 인터페이스는 실험적인 상태로 유지되는 동안 크게 변경될 가능성은 낮지만 그 과정에서 주요 변경 사항이 있을 수 있습니다.
채널은 가까운 미래에도 Nix를 사용하는 “공식적인” 방법으로 계속 사용될 것입니다. 그러나 이미 Nix 사용자인 경우 플레이크 사용법을 배우거나 Nix를 이제 막 시작하는 경우 채널 대신 플레이크로 Nix 여정을 시작하는 것이 좋습니다.
Nix _플레이크_는 루트에 flake.nix와 flake.lock이 있는 디렉터리로, 다른 사용자가 패키지 빌드, 프로그램 실행, 개발 환경 사용 또는 NixOS 시스템 구축과 같은 작업을 수행하는 데 사용할 수 있는 Nix 표현식을 출력합니다.
필요한 경우 플레이크는 다른 플레이크의 출력을 입력으로 사용할 수 있습니다.
플레이크를 Nix 코드의 처리기로 생각하면 도움이 될 수 있습니다. 플레이크는 Nix 표현식을 입력으로 받아 패키지 정의, 개발 환경 또는 NixOS 구성과 같이 Nix가 사용할 수 있는 것을 출력합니다.
따라서 플레이크는 일종의 체인을 형성합니다. 예를 들어, Nixpkgs에서 출력한 도우미 함수를 사용하여 패키지 빌드를 정의하는 플레이크를 만들었다고 가정해 보겠습니다. 그러면 제 팀원은 제 플레이크의 패키지 정의를 Nix 개발 환경의 일부로 사용할 수 있습니다. 그런 다음 다른 팀은 해당 개발 환경을 프로젝트 중 하나에 사용할 수 있습니다. 이런 식으로 계속됩니다.
플레이크 참조
_플레이크 참조_는 플레이크가 있는 위치를 문자열로 표현한 것입니다. 플레이크 참조는 다음 두 곳에서 사용됩니다.
- 플레이크 입력 선언에서 플레이크의 출력에 의존합니다.
nix run github:DeterminateSystems/flake-checker(flake-checker 프로그램 실행)와 같은 명령을 실행할 때 셸 환경에서 사용됩니다.
다음은 몇 가지 플레이크 참조 예시입니다.
| 참조 | 설명 |
|---|---|
path:/home/nix-stuff/my-flake | 현재 호스트의 /home/nix-stuff/my-flake 디렉터리 |
github:DeterminateSystems/zero-to-nix | DeterminateSystems/zero-to-nix GitHub 리포지토리 |
github:DeterminateSystems/zero-to-nix/other | DeterminateSystems/zero-to-nix GitHub 리포지토리의 other 브랜치 |
github:DeterminateSystems/zero-to-nix/d51c83a5d206e882a6f15a282e32b7079f5b6d76 | DeterminateSystems/zero-to-nix GitHub 리포지토리의 커밋 d51c83a5d206e882a6f15a282e32b7079f5b6d76 |
github:DeterminateSystems/zero-to-nix/pull/2/head | DeterminateSystems/zero-to-nix GitHub 리포지토리의 풀 리퀘스트 1 |
nixpkgs | Nixpkgs의 nixpkgs-unstable 브랜치의 최신 리비전 (github:NixOS/nixpkgs의 별칭) |
nixpkgs/release-22.11 | Nixpkgs의 release-22.11 브랜치 |
https://flakehub.com/f/NixOS/nixpkgs/0.2405.* | nixos-24.05 브랜치의 최신 리비전 |
공식 문서에서 플레이크 참조에 대한 보다 체계적인 설명을 찾을 수 있습니다.
참조 및 리비전
플레이크 참조는 항상 플레이크의 특정 리비전에 대한 것입니다. 예를 들어 Nixpkgs는 플레이크이지만 Nixpkgs의 각 리비전(수천 개가 있음)에는 플레이크 참조가 있습니다.
플레이크 입력
_플레이크 입력_은 플레이크를 빌드하는 데 필요한 Nix 종속성입니다. 세트의 각 입력은 github, 일반 git 리포지토리, 심지어 파일 시스템과 같은 다양한 소스에서 가져올 수 있습니다.
또한 입력은 서로의 입력을 수정하여 예를 들어 여러 종속성이 모두 동일한 버전의 nixpkgs에 의존하도록 할 수 있습니다.
이는 inputs.<input>.follows 속성을 통해 수행됩니다.
{ inputs = { nixpkgs.url = "github:NixOS/nixpkgs"; };}Nix 매뉴얼에서 플레이크 입력 스키마에 대한 전체 분석을 찾을 수 있습니다.
flake.lock 파일
모든 플레이크 입력은 flake.lock이라는 잠금 파일의 특정 리비전에 고정됩니다.
이 파일은 리비전 정보를 JSON으로 저장합니다.
flake.lock 파일은 Nix 플레이크가 순전히 결정적인 출력을 갖도록 보장합니다.
함께 제공되는 flake.lock이 없는 flake.nix 파일은 불완전하고 일종의 프로토 플레이크로 간주되어야 합니다.
nix build, nix develop 또는 nix flake show와 같이 플레이크에 대해 실행되는 모든 Nix CLI 명령은 flake.lock을 생성합니다.
다음은 Nixpkgs를 특정 리비전에 고정하는 flake.lock 파일의 예제 섹션입니다.
{ "nodes": { "nixpkgs": { "locked": { "lastModified": 1668703332, // 플레이크 내용의 SHA "narHash": "sha256-PW3vz3ODXaInogvp2IQyDG9lnwmGlf07A6OEeA1Q7sM=", // GitHub 조직 "owner": "NixOS", // GitHub 리포지토리 "repo": "nixpkgs", // 특정 리비전 "rev": "de60d387a0e5737375ee61848872b1c8353f945e", // 입력 유형 "type": "github" } } // 기타 입력 }}이 flake.lock이 이 입력 블록과 함께 flake.nix 옆에 있다면…
{ inputs = { nixpkgs.url = "nixpkgs"; };
outputs = { self, nixpkgs }: { # 여기에 출력 정의 };}…nixpkgs 속성은 해당 리비전 정보가 Nix 코드 자체에 없더라도 암시적으로 de60d387a0e5737375ee61848872b1c8353f945e 리비전에 고정됩니다.
플레이크 레지스트리
플레이크 레지스트리는 전체 플레이크 참조 대신 기호 식별자를 사용하여 플레이크를 참조할 수 있도록 하는 편의 기능입니다.
가장 널리 사용되는 기호 식별자는 nixpkgs이며, 이는 github:NixOS/nixpkgs/nixpkgs-unstable 플레이크 참조의 별칭입니다.
접할 수 있는 몇 가지 기호 식별자:
| 기호 식별자 | 전체 플레이크 참조 |
|---|---|
nixpkgs | github:NixOS/nixpkgs/nixpkgs-unstable |
flake-utils | github:numtide/flake-utils |
home-manager | github:nix-community/home-manager |
전체 기본 전역 플레이크 레지스트리는 JSON 파일로 유지됩니다.
다음은 기호 식별자를 사용하는 예제 플레이크입니다.
{ outputs = { self, nixpkgs, flake-utils }: let pkgs = import nixpkgs { inherit system; }; in flake-utils.lib.eachDefaultSystem (system: { devShells.default = pkgs.mkShell { packages = with pkgs; [ curl git jq wget ]; }; });}이 플레이크에서는 inputs 블록이 생략되었습니다.
플레이크 레지스트리 사용은 항상 선택 사항입니다.
플레이크 출력
_플레이크 출력_은 플레이크가 빌드의 일부로 생성하는 것입니다. 각 플레이크는 동시에 다음과 같은 다양한 출력을 가질 수 있지만 이에 국한되지는 않습니다.
플레이크 출력은 해당 플레이크의 각 입력(입력 섹션에서 선택한 식별자 이름 지정)을 포함하는 속성 세트를 입력으로 받는 함수에 의해 정의됩니다.
함수 내보내기
패키지 및 NixOS 구성과 같은 것 외에도 플레이크는 다른 곳에서 사용할 Nix 함수를 출력할 수도 있습니다.
예를 들어 Nixpkgs는 lib 속성을 통해 많은 도우미 함수를 출력합니다.
lib 규칙 함수를 출력하는 데 lib를 사용하는 규칙은 Nixpkgs뿐만 아니라 다른 많은 Nix 프로젝트에서도 준수됩니다. 그러나 원하는 속성을 통해 함수를 자유롭게 출력할 수 있습니다.
다음은 이름을 입력으로 받아 해당 이름을 가진 사람에게 인사하는 문자열을 출력하는 sayHello 함수를 lib 속성을 통해 출력하는 예제 플레이크입니다.
{ outputs = { self }: { lib = { sayHello = name: "Hello there, ${name}!"; }; };}그런 다음 다른 Nix 플레이크는 이 플레이크를 입력으로 지정하고 원하는 용도로 sayHello를 사용할 수 있습니다.
시스템 특정성
패키지, 개발 환경 및 NixOS 구성을 포함하여 일부 플레이크 출력은 시스템 특정적이어야 합니다.
다음은 x86_64-linux 시스템(64비트 AMD/Intel Linux)에서 사용할 수 있는 패키지를 출력하는 예제 플레이크입니다.
{ outputs = { self, nixpkgs }: let # 시스템 선언 system = "x86_64-linux"; # 시스템별 Nixpkgs 버전 사용 pkgs = import nixpkgs { inherit system; }; in { # 플레이크의 기본 패키지로 `ponysay` 출력 packages.${system}.default = pkgs.ponysay; };}그러나 많은 경우 여러 시스템에 대해 패키지 또는 개발 환경과 같은 것을 출력해야 합니다.
flake-utils와 같은 도우미 라이브러리는 이를 수행하는 편리한 메커니즘을 제공합니다.
다음과 같이 Nix 함수를 사용할 수도 있습니다.
{ outputs = { self, nixpkgs }: let # 출력을 제공할 시스템 세트 allSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
# 원하는 시스템에 대한 시스템별 Nixpkgs를 제공하는 함수 forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f { pkgs = import nixpkgs { inherit system; }; }); in { packages = forAllSystems ({ pkgs }: { default = { # 패키지 정의 }; }); };}플레이크 템플릿
플레이크 템플릿을 사용하면 미리 제공된 콘텐츠로 새 Nix 프로젝트를 초기화하거나 기존 프로젝트에 파일 세트를 추가할 수 있습니다.
nix flake init 명령을 사용하여 플레이크 템플릿을 초기화할 수 있습니다.
플레이크는 templates 속성을 사용하여 템플릿을 출력할 수 있습니다.
다음은 예시입니다.
{ outputs = { self }: { templates = { starter-template = { path = ./my-starter-template; description = "새 Nix 프로젝트를 위한 시작 템플릿"; }; }; };}이 템플릿 정의에 대해 nix flake init --template <reference>를 실행하면 Nix는 ./my-starter-template 디렉터리의 내용을 현재 디렉터리에 복사합니다(기존 파일 덮어쓰기 없음).