Switching to GNU Guix: A Beginner's Perspective
GNU Guix로의 전환 — 초보자의 시선에서 본 한 달간의 이주기
10년 넘게 Arch Linux를 쓰던 홈서버 운영자가 선언적 OS를 찾아 NixOS를 검토한 끝에 GNU Guix로 전환한 경험기입니다. Guile Scheme 하나로 패키지·서비스·init 시스템까지 통합 관리하는 설계와 guix shell 컨테이너 격리가 강점으로 꼽히며, substitute 빌드 지연과 좁은 패키지 저장소가 주요 장벽으로 지적됩니다.
- 주제
본문
저자는 10년 이상 Arch Linux를 써온 사용자로, Home Assistant·로컬 DNS·백그라운드 잡·개발 샌드박스를 돌리는 24시간 가동 홈서버를 운영하고 있습니다. 수년간의 점진적 수정으로 설정 상태가 /etc, /usr, systemd 유닛, 패키지 매니저 트랜잭션 곳곳에 흩어지는 '설정 엔트로피'가 쌓였고, 변경 때마다 어떤 파일을 언제 왜 고쳤는지 일일이 기록해야 했습니다. 최근 AUR 보안 사고와 Omarchy 관련 논의를 계기로 선언적이고 재현 가능하며 코드로 관리되는 OS를 찾기 시작했습니다.
NixOS가 아니라 GNU Guix를 택한 이유
NixOS를 VM에 올려 기존 서비스를 재현해 본 실험 자체는 성공적이었지만, 문서가 큰 마찰이었습니다. 새 nix CLI와 Flakes가 아직 실험적 기능이라 기본 활성화되지 않고 생태계 전반에 표준화되지 않았으며, 위키가 두 개로 나뉘어 튜토리얼과 문서가 서로 어긋났습니다. 이후 System Crafters의 David Wilson이 올린 'Why I Choose Guix Over NixOS' 영상 등을 통해 Guix를 접했고, 같은 함수형 패키지 관리·선언적 설정·원자적 롤백이라는 토대 위에서 설계가 더 일관되다고 판단했습니다. 차이점은 네 가지로 정리됩니다. 첫째 언어 — Nix의 전용 DSL 대신 Guix는 범용 Scheme인 GNU Guile로 작성하며, Emacs Lisp에 익숙한 Emacs 사용자에게 일급 함수·매크로·모듈을 갖춘 진짜 프로그래밍 언어로 다가왔습니다. 둘째 init 시스템 — NixOS의 systemd 대신 GNU Shepherd를 쓰며, 패키지 레시피부터 데몬·PID 1까지 하나의 언어와 데이터 모델을 공유합니다. 셋째 문서 — 공식 레퍼런스 매뉴얼이 일관되고 포괄적입니다. 넷째 철학 — GNU FSDG를 엄격히 따라 Linux-libre 커널과 자유 소프트웨어만 기본 제공합니다. 유선 이더넷으로 연결된 홈서버에는 비자유 Wi-Fi 펌웨어가 필요 없어 이 순수성이 오히려 장점이었다고 저자는 말합니다.
초보자가 꼽은 Guix의 강점
전체 OS 설정이 코드로 존재하고 Git으로 추적됩니다. Guix System(OS 선언·데몬·커널 매개변수)과 Guix Home(사용자 패키지·쉘 환경·dotfiles)을 Org Babel을 활용한 단일 리터레이트 파일 guix.org로 관리해, 설치된 패키지와 활성 서비스를 코드베이스에서 바로 확인할 수 있습니다. simple-service 확장 메커니즘으로는 Home Assistant OCI 컨테이너와 그것을 앞세우는 Nginx 리버스 프록시 설정을 같은 설정 블록에 나란히 배치할 수 있어, 전통 배포판처럼 systemd 유닛과 /etc/nginx/conf.d/에 설정을 쪼갤 필요가 없습니다. Shepherd Timer도 강점입니다. systemd에서 .service와 .timer를 따로 선언해야 하는 반면, Guix에서는 실행 스크립트·의존성·cron 스케줄을 하나의 Guile 식으로 정의합니다 — 저자는 DuckDNS IP 갱신을 5분 주기로 돌리는 예시를 보여줍니다. guix shell은 일회성 도구를 프로필을 오염시키지 않고 임시 환경에서 실행하게 하고, --container 모드는 --share·--network로 노출 범위를 지정한 경량 샌드박스를 만들어 줍니다. 저자는 Antigravity CLI 같은 AI 코딩 에이전트를 현재 디렉터리와 설정 경로만 공유한 격리 환경에서 실행합니다. 아울러 stage0/Mes 부트스트랩으로 부트스트랩 바이너리 시드를 약 357바이트까지 줄인 아키텍처적 엄밀함이 스택 전체에 대한 신뢰를 준다고 평가합니다.
겪은 문제와 대처법
Guix는 본질적으로 소스 기반 배포판이라, ci.guix.gnu.org나 Bordeaux 같은 substitute 서버가 새로 pull한 채널 커밋을 아직 빌드하지 않았다면 로컬 컴파일로 떨어집니다. guix challenge(빌드 재현성 검증)나 guix time-machine(과거 리비전 이동) 같은 강력한 기능의 밑바탕이지만 홈서버에서 장시간 빌드를 기다리는 것은 번거롭습니다. 저자의 실용적 우회책은 channels.scm에서 guix pull을 하루이틀 전 특정 커밋으로 고정해 substitute가 이미 캐시된 상태를 보장하는 것이며, Codeberg 미러로 pull 속도도 개선했습니다. 두 번째 장벽은 패키지 갭입니다. 공식 채널은 libre 기준이 엄격하고 AUR보다 카탈로그가 작아 hugo, caddy 같은 흔한 도구도 없습니다. 대처법은 네 가지입니다. ① Scheme으로 패키지 정의를 직접 작성 — Hugo는 공식 사전빌드 바이너리를 받는 로컬 정의로 해결했습니다. ② 언어 생태계 도구는 guix shell로 임시 실행 — 'guix shell node -- npx -y wrangler'로 블로그를 Cloudflare에 배포합니다. ③ guix import로 PyPI·Crates.io·CPAN·GNU ELPA 등에서 패키지 정의를 자동 생성합니다. ④ 이미 일급 지원되는 대안으로 전환 — 서드파티 플러그인을 얹은 Caddy 대신 Guix 네이티브 서비스로 잘 지원되는 Nginx와 Certbot 조합으로 돌아섰습니다.
한 달간의 사용 결론은, Git을 통한 선언적 OS 상태 관리가 설정 드리프트를 제거했고 Guile Scheme이 Emacs와 어우러지는 일관된 환경을 제공한다는 것입니다. 작은 패키지 생태계와 substitute 타이밍 조정이 필요하지만 안정성·재현성·컨테이너 격리가 신뢰할 만한 기반이라고 저자는 평가하며, 여가 시간에 Scheme 이해를 깊게 하려고 SICP를 읽기 시작했다고 덧붙입니다.
Lobsters 반응
- @PuercoPop — substitute 지연 문제에 동의하며, Guix가 패키지를 master에 머지한 뒤 빌드하는 대신 아티팩트가 먼저 빌드된 후에 메인 브랜치로 승격하는 방식이었으면 한다는 개선 의견을 내놓았습니다.
원문: Lobsters / 번역·요약: Trawling