Flakes 닉스와 클래식 닉스 비교

Posted on April 18, 2025

Flakes 닉스로 설정한 것과, 같은 동작을 하는 클래식 닉스 설정을 보여주고, “Flakes를 쓰면 이런 이런 부분이 좋다”라고 설명하는 튜토리얼을 찾아 헤맸는데, 아직 적당한 걸 못 찾았습니다. 그래서 직접 예시를 만들어 보긴 했는데, 아직 Flakes의 특징이 썩 잘 보이는 편은 아닌 것 같습니다. 일단 올려두고, Flakes 경험이 쌓이면 더 보강하도록 하겠습니다.

Flakes 닉스는, 클래식 닉스가 하지 못하는 일을 하는 것이 아니라, 재현성이 떨어지는 방식으로 설정하지 못하도록, 빡빡한 틀을 제공하는 것과 비슷해 보입니다.

간단한 비교

Flakes 닉스

# flake.nix
{
  description = "A flake for building Hello World";
  inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-20.03; # 명시적인 버전 고정
  outputs = { self, nixpkgs }: {
    defaultPackage.x86_64-linux =
      with import nixpkgs { system = "x86_64-linux"; }; # 기본 여러 시스템에 대응
      stdenv.mkDerivation {
        name = "hello";
        src = self;
        buildPhase = "gcc -o hello ./hello.c";
        installPhase = "mkdir -p $out/bin; cp hello $out/bin";
      };
  };
}

클래식 닉스

# default.nix
{ pkgs ? import <nixpkgs> {} }: # 시스템에 설정된 nixpkgs 경로에서 불러온다.
pkgs.stdenv.mkDerivation { # 하나의 시스템만 염두
  name = "hello";
  src = ./hello.c;
  buildPhase = "${pkgs.gcc}/bin/gcc -o hello hello.c";
  installPhase = " mkdir -p $out/bin; cp hello $out/bin";
}

위 작업만으론 Flakes의 필요성이 잘 안보입니다.

외부 Git을 참고하는 설정 비교

Flakes 닉스

# https://github.com/lionhairdino/hello-flake/flake.nix
{
  description = "Hello World package";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
  outputs = { self, nixpkgs }:
    let
      system = "x86_64-linux";
      pkgs = import nixpkgs { inherit system; };
    in {
      packages.${system}.hello = pkgs.stdenv.mkDerivation {
        pname = "hello";
        version = "1.0";
        src = ./.;
        buildPhase = "echo 'Hello from external flake!' > hello.txt";
        installPhase = "mkdir -p $out; cp hello.txt $out/";
      };
    defaultPackage.${system} = self.packages.${system}.hello;
  };
}

위에 Flakes로 설정한 걸, 클래식 닉스로 구현하면 아래와 같습니다.

클래식 닉스

# my-local/flake.nix
{
  description = "My project that uses an external flake";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
    hello-flake.url = "github:lionhairdino/hello-flake";
  };

  outputs = { self, nixpkgs, hello-flake, ... }: 
  let
    system = "x86_64-linux";
    pkgs = import nixpkgs { inherit system; };
    externalHello = hello-flake.packages.${system}.hello;
  in {
    packages.${system}.my-app = pkgs.stdenv.mkDerivation {
      pname = "my-app";
      version = "1.0";
      buildInputs = [ externalHello ];
      unpackPhase = "true";
      buildPhase = ''
        echo "use the external hello package"
        cp ${externalHello}/hello.txt .
      '';
      installPhase = ''
        mkdir -p $out
        cp hello.txt $out/
      '';
    };
    defaultPackage.${system} = self.packages.${system}.my-app;
  };
}
# hello-flake.nix
let
  nixpkgs = import <nixpkgs> {};
  external-src = builtins.fetchGit {
    url = "https://github.com/lionhairdino/hello-flake.git";
    rev = "89af20541eccff5e2c9d3d4bd14d582dcb4edf33"; # 커밋 해시 고정
  };
in
  nixpkgs.stdenv.mkDerivation {
    pname = "hello";
    version = "1.0";
    src = external-src;
    buildPhase = "echo 'Hello from external!' > hello.txt";
    installPhase = "mkdir -p $out; cp hello.txt $out/";
  }
# hello-my-app.nix
{ pkgs, externalHello }:

pkgs.stdenv.mkDerivation {
  pname = "my-app";
  version = "1.0";
  unpackPhase = "true";
  buildPhase = ''
    echo "my-app use the external hello package"
    cp ${externalHello}/hello.txt .
  '';
  installPhase = ''
    mkdir -p $out
    cp hello.txt $out/
  '';
}
# default.nix
let
  pkgs = import <nixpkgs> {};
  externalHello = import ./hello-flake.nix;
in
  pkgs.callPackage ./hello-my-app.nix {
    inherit externalHello;
  }
Github 계정이 없는 분은 메일로 보내주세요. lionhairdino at gmail.com