Nix 시작하기

Eunmin Kim·2024년 11월 22일

Nix 패키지 관리도구

Nix 패키지 관리 도구는 특정 언어를 넘어 가상 환경을 만들어 주는 관리 도구입니다. NixOS도 있는데 이것은 Nix를 기반으로 하는 운영체제 입니다.

설치

다음 명령어로 macOS에 설치합니다.

$ sh <(curl -L https://nixos.org/nix/install)

설치가 되었다면 시스템 환경 변수를 새로 읽기 위해 터미널을 새로 띄워줍니다. 그리고 flake라는 최신 기능을 쓰기 위해 ~/.config/nix/nix.conf 파일을 열어 다음 설정을 넣어줍니다.

experimental-features = nix-command flakes

Hello World

Nix가 설치되었다면 다음 명령어를 입력해서 잘 동작하는지 확인해봅시다.

$ nix shell nixpkgs#hello --command hello
Hello, world!

위 명령어는 nixpkgs에서 hello 라고 하는 최신 버전의 커맨드라인 도구를 받아 실행하는 명령어 입니다.

nix shell 명령어는 바로 뒤에 인자인 nixpkgs#hello 패키지가 설치되어 있는 가상 환경을 만들어 줍니다. 그리고 가상 환경에서 명령어를 실행하려면 --command 뒤에 명령어를 써주면 됩니다.

만약 --command 명령어를 생략하면 현재 쉘 환경이 가상 환경이 됩니다.

$ hello
zsh: command not found: hello
$ nix shell nixpkgs#hello
$ hello
Hello, world!

원래 내 환경에는 hello 라는 툴이 없지만 nix shell 패키지 명령어로 가상 환경을 만들고 나면 hello 커맨드라인 툴을 쓸 수 있습니다. 터미널을 종료해서 쉘을 나가게 되면 가상 환경은 사라지기 때문에 hello 명령어를 쓸 수 없습니다.

다음은 패키지를 flake.nix 파일로 관리해봅시다.

패키지 파일로 관리하기

다음은 nixpkgs에 있는 파이썬 패키지를 가지고 연습해 봅시다. 앞에서 확인해 본 것처럼 파이썬 3.9 버전을 실행할 수 있는 Nix 환경을 만들어 봅시다.

$ python --version
Python 3.10.14
$ nix shell nixpkgs#python39 --command python --version
Python 3.9.20

원래 쉘의 파이썬 버전은 3.10이지만 python39 패키지가 포함된 Nix 환경에서는 파이썬 버전이 3.9인 것을 볼 수 있습니다.

다음 명령어로 mypython 폴더를 만들고 그 안에 기본 flake.nix 파일을 만들어봅시다.

$ mkdir mypython
$ cd mypython
$ nix flake init
wrote: ".../flake.nix"

위 명령어를 실행하면 다음과 같은 flake.nix 파일이 생깁니다.

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };

  outputs = { self, nixpkgs }: {

    packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello;

    packages.x86_64-linux.default = self.packages.x86_64-linux.hello;

  };
}

이 파일은 Nix 언어로 되어 있습니다. 자세한 내용은 문서를 참고하세요. 여기서는 python39 패키지를 사용하기 위해 outputs 부분을 아래와 같이 바꿔줍니다.

{
  description = "A very basic flake";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };

  outputs = { self, nixpkgs }:
    let
      system = "aarch64-darwin";
      pkgs = import nixpkgs { inherit system; };
    in {
      devShells.${system}.default = pkgs.mkShell {
        buildInputs = [
          pkgs.python312
        ];
      };
    };
}

system 값은 사용할 환경을 지정해 줍니다. 이 문서는 Apple Silicon 맥을 사용하고 있기 때문에 aarch64-darwin 을 적어줬습니다. 인텔 맥이면 x86_64-darwin 이나 인탤 기반 리눅스라면 x86_64-linux 등으로 바꿔주면 됩니다.

이제 python39 패키지가 있는 Nix 환경에서 파이썬 버전을 확인해 봅시다. 여기서는 nix shell 대신 nix develop 이라는 명령어를 사용합니다.

$ nix develop --command python --version
Python 3.12.7

위 명령어를 실행하면 같은 폴더에 flake.nix 파일을 읽어 Nix 환경을 만들고 명령어를 실행해줍니다. 만약 --command 인자를 빼고 실행하면 Nix 환경에서 새로운 bash 쉘을 실행해줍니다.

$ nix develop                           
bash-5.2$ python --version
Python 3.12.7
bash-5.2$ exit
exit
$

direnv로 Nix 환경 편리하게 쓰기

direnv 툴을 사용하면 Nix 환경을 조금 더 편하게 쓸 수 있습니다. 먼저 direnv 를 설치합니다.

$ brew install direnv

위 파이썬 예제에서 만든 mypython 폴더에 다음과 같이 .envrc 파일을 만들어 줍니다.

$ echo "use flake" >> .envrc
direnv: error .../mypython/.envrc is blocked. Run `direnv allow` to approve its content

그리고 나면 에러가 발생하는데 내용에 나온 것 처럼 direnv allow . 명령어로 mypython 폴더에서 direnv를 쓸 수 있게 허용해 줍니다.

이제 mypython 폴더에 들어오면 자동으로 Nix 환경을 구성해줍니다.

$ cd mypyhton
direnv: loading .../mypython/.envrc                                                                                                        
direnv: using flake
direnv: export +AR +AS +CC +CONFIG_SHELL +CXX +DETERMINISTIC_BUILD +DEVELOPER_DIR +HOST_PATH +IN_NIX_SHELL +LD +LD_DYLD_PATH +MACOSX_DEPLOYMENT_TARGET +NIX_APPLE_SDK_VERSION +NIX_BINTOOLS +NIX_BINTOOLS_WRAPPER_TARGET_HOST_aarch64_apple_darwin +NIX_BUILD_CORES +NIX_BUILD_TOP +NIX_CC +NIX_CC_WRAPPER_TARGET_HOST_aarch64_apple_darwin +NIX_CFLAGS_COMPILE +NIX_DONT_SET_RPATH +NIX_DONT_SET_RPATH_FOR_BUILD +NIX_DONT_SET_RPATH_FOR_TARGET +NIX_ENFORCE_NO_NATIVE +NIX_HARDENING_ENABLE +NIX_IGNORE_LD_THROUGH_GCC +NIX_LDFLAGS +NIX_NO_SELF_RPATH +NIX_STORE +NM +OBJCOPY +OBJDUMP +PATH_LOCALE +PYTHONHASHSEED +PYTHONNOUSERSITE +PYTHONPATH +RANLIB +SDKROOT +SIZE +SOURCE_DATE_EPOCH +STRINGS +STRIP +TEMP +TEMPDIR +TMP +ZERO_AR_DATE +__darwinAllowLocalNetworking +__impureHostDeps +__propagatedImpureHostDeps +__propagatedSandboxProfile +__sandboxProfile +__structuredAttrs +buildInputs +buildPhase +builder +cmakeFlags +configureFlags +depsBuildBuild +depsBuildBuildPropagated +depsBuildTarget +depsBuildTargetPropagated +depsHostHost +depsHostHostPropagated +depsTargetTarget +depsTargetTargetPropagated +doCheck +doInstallCheck +dontAddDisableDepTrack +mesonFlags +name +nativeBuildInputs +out +outputs +patches +phases +preferLocalBuild +propagatedBuildInputs +propagatedNativeBuildInputs +shell +shellHook +stdenv +strictDeps +system ~PATH ~TMPDIR ~XDG_DATA_DIRS
$

그럼 이 폴더에서 파이썬 버전을 확인하면 Nix 환경에 정의된 버전인 3.9 버전이 되는 것을 볼 수 있습니다.

$ python --version
Python 3.12.7

mypython 폴더를 벗어나면 시스템에 설정된 파이썬 버전으로 돌아옵니다.

$ cd .. 
$ python --version
Python 3.10.14

Nix 하스켈 개발 환경 만들기

Nix haskell-template을 사용하면 Nix 개발 환경을 쉽게 만들 수 있습니다. 다음 명령어로 새로운 하스켈 프로젝트를 만듭니다. yourproject 부분은 원하는 이름으로 바꾸면 됩니다.

$ nix --accept-flake-config run github:juspay/omnix -- \
  init github:srid/haskell-template -o ./yourproject

yourproject 폴더에 들어가면 direnv가 동장해서 쉘에서 Nix 환경이 뜹니다. 프로젝트를 빌드하고 실행해 보려면 Nix 환경에서 just run 하면 됩니다.

$ just run

의존성을 추가하려면 hello.cabal 파일을 열어서 build-depends 아래 의존성을 추가해주면 됩니다. 아래는 ulid 패키지를 추가한 예입니다.

build-depends:
  ...
  , ulid

패키지 버전은 nixpkgs에 있는 hakellPackages 하위에 있는 버전으로 자동으로 선택됩니다.

profile
Functional Programmer @Constacts, Inc.

0개의 댓글