Nix 패키지 관리 도구는 특정 언어를 넘어 가상 환경을 만들어 주는 관리 도구입니다. NixOS도 있는데 이것은 Nix를 기반으로 하는 운영체제 입니다.
다음 명령어로 macOS에 설치합니다.
$ sh <(curl -L https://nixos.org/nix/install)
설치가 되었다면 시스템 환경 변수를 새로 읽기 위해 터미널을 새로 띄워줍니다. 그리고 flake라는 최신 기능을 쓰기 위해 ~/.config/nix/nix.conf
파일을 열어 다음 설정을 넣어줍니다.
experimental-features = nix-command flakes
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
를 설치합니다.
$ 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 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 하위에 있는 버전으로 자동으로 선택됩니다.