Nix 시작하기

Eunmin Kim·2024년 11월 22일
2

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개의 댓글

관련 채용 정보