Nix로 Docker 이미지를 빌드하면 결정론적이고 최소한의 레이어를 가진 이미지를 얻는다. Docker 빌드의 비결정성 문제를 해결하는 접근법.

핵심 내용

Docker 빌드의 문제 (출처: Nix is a better Docker image builder than Docker’s image builder):

  • 비결정적: 빌드 중 인터넷 접근 → 같은 Dockerfile이라도 시점에 따라 다른 결과
  • apt-get upgrade의 shadow copy로 불필요한 디스크 사용
  • 베이스 이미지 EOL 시 재현 불가 (Ubuntu 18.04 등)
  • 이 문제는 주로 새벽 4시에 발생 (SRE 경험담)

Nix의 이점:

  • 모든 의존성을 사전 해시 → 동일 입력이면 동일 출력
  • 의존성 트리 분석 → 최소 Docker 레이어로 패키징
  • 코드 한 줄 변경 시 변경분만 push
  • 인터넷 연결 없이 빌드 가능

실전 사용

Go 앱을 Nix로 빌드하여 Docker 이미지로 만드는 예시:

bin = pkgs.buildGoModule {
  pname = "douglas-adams-quotes";
  inherit version;
  src = ./.;
  vendorHash = null;
};

도입 전략: 기존 CI/CD를 바꾸지 않고 Docker 이미지 빌드만 Nix로 교체하는 것이 최소 진입점. Fly.io, Railway, Google Cloud Functions 등 Docker 이미지를 받는 플랫폼에서 바로 사용.

외부 Go 의존성이 있으면 vendorHash를 지정하거나 gomod2nix(https://github.com/nix-community/gomod2nix)로 자동화.

관련 링크