지피지기 백전백퇴

Nix로 dotfiles 관리하기


개요

Unix-like 환경이라면 home-manager를 이용해서 각종 설정파일들을 관리할 수도 있다.

왜 이걸 하는데?

당신이 심혈을 기울여 2000줄에 달하는 neovim 설정을 만들었다고 생각해봐라. 당연히 version control로 관리해야 한다. 근데 설치할 때 모양빠지는 cp 대신 기깔나는 빌드 시스템을 관리하면 개쩔것 같지 않은가…?

그러니까 정리하면

  • 여러개의 시스템에 비슷한 설정을 관리하는데, 시스템마다 살짝 설정이 달라져서 뭔가 스크립팅이 필요하다면?
  • 개쩌는 설정을 만들었기 때문에 실수로라도 로컬 변경을 허용하고 싶지 않다면?
    • Nix에서 만든 파일은 뭔가 쓰기불가된 파일을 symlink하기 때문에 수정이 불가능해진다.
  • 단순 설정파일을 넘어서 뭔가 systemd 서비스같은것도 쓰고싶고 설치할 때 restart 한다던지 하는 추가 설치작업도 같이 수행하고 싶다면?
  • 설정파일을 만들 때 외부 의존성이 필요한 경우라면?

이런 경우에는 nix를 이용해서 설정을 관리하는 것이 좋다.

반대로 다음과 같은 경우라면 굳이…?

  • 파일 한두개 수준의 찌질한 설정
  • 뭔가 잘못돼도 손으로 고칠 수 있는 대범함
  • 설정은 설정일 뿐 별다른 연동이 필요없다
  • 외부 의존성은 사치, 그때그때 의존성을 따로 설치하는 게 낫다
  • Nix 말고도 설정 파일을 수정하는 프로그램이 있는 경우
    • 이를테면 Rclone의 경우, 새 연결을 설정할 때 rclone 앱이 직접 설정 파일을 수정한다. 하지만 Nix에서 관리하는 파일은 쓰기불가 tag가 붙기 때문에 설정에 실패하고 만다…

하여튼 설치하려면

이 가이드를 참조하면 좋다.

flake.nix

{
  description = "A flake for managing my dotfiles configuration.";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };
  outputs = { nixpkgs, home-manager, ... }:
    let
      lib = nixpkgs.lib;
      system = "x86_64-linux";
      pkgs = import nixpkgs { inherit system; };
    in {
      homeConfigurations = {
        yourhost = home-manager.lib.homeManagerConfiguration {
          inherit pkgs;
          modules = [ ./home.nix ];
        };
      };
    };
}

결론?

주로 쓰는 개발 호스트에선 그때그때 조금씩 수정할 일이 많은데 NixOS는 좀 안맞는다. 다만 해당 설정을 여러군데에서 적용할 필요가 있다면 쓸만할지도?

난 그냥 NixOS 쓰는 서버에서만 쓸란다…