# 더 작은 NixOS ISO를 만들 수 있을까?

> Clean Markdown view of GeekNews topic #30654. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=30654](https://news.hada.io/topic?id=30654)
- GeekNews Markdown: [https://news.hada.io/topic/30654.md](https://news.hada.io/topic/30654.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-06-20T10:11:17+09:00
- Updated: 2026-06-20T10:11:17+09:00
- Original source: [natkr.com](https://natkr.com/2026-06-19-nixos-but-smol/)
- Points: 1
- Comments: 1

## Topic Body

- NixOS는 설정만으로 VM이나 ISO를 만들기 쉽지만, 최소에 가까운 라이브 이미지도 처음부터 **458MiB**로 생성되어 Alpine VM ISO 약 **66MiB**와 큰 차이를 보임
- 크기의 대부분은 **nix-store.squashfs**가 차지했고, 그 안에는 Python 3.13.13, Linux modules, systemd, Perl, GRUB, 문서, Nix 관련 의존성이 들어 있었음
- `nix.enable = false`, `documentation.enable = false`, `register-nix-paths` 제거를 거치며 ISO는 **458MiB → 384MiB → 360MiB**로 줄었고 Boost 의존성도 빠짐
- OpenSSH 클라이언트, 기본 패키지, GRUB 설치 도구, 런타임 커널 모듈, Perl 기반 활성화 경로까지 걷어내 최종 크기는 **183MiB**까지 내려감
- 작은 실험용 부팅 이미지에는 참고할 만하지만, 필요한 기능을 많이 제거하므로 데스크톱이나 중요한 환경에 그대로 쓰기는 어려움

---

### NixOS 설정에서 ISO 만들기
- [NixOS](https://nixos.org/)는 설정을 기반으로 VM을 쉽게 만들 수 있음
  - `nixos-rebuild build-vm`은 현재 시스템 설정의 VM을 생성함
  - `pkgs.nixos`를 사용하면 시스템 설정이 아니더라도 임의 설정으로 VM을 만들 수 있음
- 기본 예시는 `system.stateVersion = "26.05"`와 `services.getty.autologinUser = "root"`만 둔 최소 VM을 생성함
- 이 VM은 **thin VM**으로 동작함
  - 디스크 이미지에는 VM 안에서 직접 만든 파일만 들어감
  - `/nix/store` 등 나머지는 호스트 OS에서 마운트됨
- 호스트에 Nix가 없거나 원격 호스트, 일반 하이퍼바이저에서 실행하려면 **자체 포함 ISO**가 필요함
- NixOS의 `iso-image.nix` 모듈을 import하면 ISO를 빌드할 수 있음
  - `image.baseName = lib.mkForce "nixos"`로 출력 ISO 이름을 지정함
  - 실행 예시는 `qemu-system-x86_64 --cdrom .../nixos.iso -m 1G --accel kvm` 형태임
  - amd64의 현대 Linux 환경이 아니라면 아키텍처나 가속 방식 변경이 필요할 수 있음

### 시작점: 458MiB ISO
- 기본 ISO 빌드 결과는 **458MiB**였음
- 이 이미지는 아직 `vim`도 포함하지 않음
  - 부팅 후 `vim` 실행 시 `command not found`가 나옴
- 비교 대상으로 든 Alpine의 VM ISO는 약 **66MiB**임
- Damn Small Linux는 훨씬 작은 크기로 완성도 있는 데스크톱 환경을 제공했던 사례로 등장함
- 목표는 Damn Small Linux 수준에 도달하는 것이 아니라, NixOS ISO를 어느 정도라도 더 줄일 수 있는지 확인하는 데 있음

### ISO 내부 크기 분석
- ISO를 마운트해 `du`로 확인하니 크기는 다음처럼 나뉨
  - `nix-store.squashfs`: **416MiB**
  - initrd: **26MiB**
  - kernel: **13MiB**
  - 전체 ISO: **458MiB**
- 핵심 크기 요인은 **주 사용자 공간**인 `nix-store.squashfs`였음
- squashfs를 마운트하면 Nix store처럼 보이는 경로들이 들어 있음
  - `python3-3.13.13`: **128MiB**
  - `linux-6.18.35-modules`: **144MiB**
  - `systemd-260.1`: **60MiB**
  - `perl-5.42.0`: **56MiB**
  - `grub-2.12`: 여러 항목 합산 약 **62MiB**
  - `nix-manual-2.34.7`, `nixos-manual-html` 등 문서도 포함됨
- ISO는 호스트에서 빌드되므로, ISO 안의 store 경로는 호스트 `/nix/store`에서도 추적할 수 있음
- `nix why-depends`로 의존성의 출처를 확인함
  - Boost는 Nix daemon 경로를 통해 들어왔음
  - `nix-daemon.conf`, `nix`, `libnixutil.so`를 거쳐 `boost-1.89.0`에 도달함

### Nix와 문서 제거
- `nix.enable = false`로 Nix 자체를 이미지에서 제거하려고 시도함
- `documentation.enable = false`로 문서도 비활성화함
- 첫 결과는 **458MiB → 384MiB**였음
- 하지만 Boost는 여전히 남아 있었음
  - `register-nix-paths.service`가 ISO store 내용을 부팅 시 등록하려고 함
  - 이 경로가 다시 Nix와 Boost를 끌어옴
- `systemd.services.register-nix-paths = lib.mkForce {}`로 해당 서비스를 비워 제거함
- 그 결과 ISO는 **360MiB**가 되었고, `nix why-depends`에서 Boost 의존성이 없다고 확인됨

### OpenSSH와 기본 패키지 제거
- 비슷한 방식으로 `environment.defaultPackages`도 비울 수 있었음
- `ssh` 제거는 더 까다로웠음
  - `modules/programs/ssh.nix`가 OpenSSH를 `environment.corePackages`에 추가함
  - 이를 제어할 `programs.ssh.enable` 같은 옵션을 찾을 수 없었음
  - `services.openssh.enable`은 서버 설정이지 클라이언트 제거 옵션이 아님
- `disabledModules`로 `programs/ssh.nix`를 제외할 수는 있었지만, 다른 모듈들이 `programs.ssh` 옵션 존재를 기대해 연쇄 오류가 발생함
- 해결책은 `programs.ssh` 옵션을 쓰지 않는 **stub 옵션**을 별도 모듈로 제공하는 방식이었음
  - `options.programs.ssh = lib.mkOption {};`
  - 이후 `disabledModules = [ "programs/ssh.nix" ];`로 실제 SSH 모듈을 제외함
- 이 과정에서 다음 설정도 함께 적용함
  - `documentation.man.enable = false`
  - `networking.firewall.enable = false`
  - `environment.defaultPackages = lib.mkForce []`

### NixOS 모듈 구조 메모
- NixOS 모듈은 크게 세 부분을 가짐
  - 모듈 수준 항목: `imports`, `disabledModules`
  - 옵션 정의: `options.*`
  - 구현: `config.*`
- 옵션을 정의하지 않는 모듈은 `config.` 접두어 없이 구현 속성을 쓰는 축약형을 사용할 수 있음
- 나머지 설정에서 축약형을 유지하기 위해, `programs.ssh` stub 옵션은 별도 import 모듈로 분리함

### GRUB 설치 도구 제거
- 남은 큰 항목 중 하나는 약 **62MiB**의 GRUB 관련 파일이었음
- 부트로더 자체는 필요하지만, 설치 도구를 모두 포함할 필요는 없다고 판단함
- NixOS ISO preset은 UEFI와 BIOS 버전 GRUB를 모두 번들함
- 이를 끄는 명확한 옵션은 없어, 더 거친 방식으로 다음 값을 재설정함
  - `system.extraDependencies = lib.mkForce []`
  - `environment.systemPackages = lib.mkForce config.environment.corePackages`
- `environment.systemPackages`를 완전히 비우지는 않음
  - `bash`가 없으면 getty가 계속 crashloop할 수 있어, 셸이 어느 정도 동작하도록 `corePackages`는 유지함

### 커널 모듈 제거
- `linux-6.18.35-modules`는 **144MiB**였고, 전체 크기의 약 4분의 1에 해당함
- NixOS에는 런타임에 사용할 커널 모듈을 제한하는 좋은 훅이 보이지 않았음
- 대신 시스템 출력에서 `kernel-modules` 폴더를 제거함
  - `system.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";`
- 이 방식은 **런타임 모듈 로딩을 사실상 비활성화**함
  - 필요한 모듈은 `boot.initrd.kernelModules` 또는 `availableKernelModules`에 넣어야 함
- 이 변경 뒤 더 편한 디스플레이 해상도로 전환하는 기능을 잃었지만, 부팅은 가능했음
- ISO 크기는 **197MiB**까지 내려감

### Perl 제거와 실험적 대체 기능
- 여전히 **56MiB**의 [Perl](https://www.perl.org/)이 포함되어 있었음
- `nix why-depends`로 확인하니 Perl은 시스템 활성화 중 사용자와 `/etc`를 구성하는 데 쓰였음
- 사용자와 `/etc` 구성을 완전히 버릴 수는 없었음
- 대신 실험적 기능으로 기존 경로를 대체함
  - `/etc` 관리는 overlay 방식 사용
  - 사용자 관리는 native [userborn](https://github.com/nikstur/userborn) 사용
- 적용한 설정은 다음과 같음
  - `system.etc.overlay.enable = true`
  - `system.etc.overlay.mutable = false`
  - `services.userborn.enable = true`
- 최종 ISO 크기는 **183MiB**가 됨

### 최종 상태와 한계
- 시작점 **458MiB**에서 최종 **183MiB**까지 줄어, 원본의 거의 3분의 1 수준이 됨
- 그래도 결과를 “좋다”고 부르기는 어렵다고 봄
- 실제로 사용해야 하는 데스크톱이나 중요한 환경에는 적합하지 않음
  - 제거한 기능들은 모두 존재 이유가 있음
- 작은 실험용 부팅 이미지가 필요하고 아주 작은 작업만 수행하면 되는 경우에는 참고할 수 있음
- 최종 설정을 그대로 복사해 쓰면 목적에 필요한 기능이 빠져 있을 수 있음

### 더 줄일 여지
- 이번 작업은 “그냥 제거 가능”하거나 비교적 명확한 대체 수단이 있는 항목에 집중함
- 더 깊은 작업이 필요한 영역도 남아 있음
  - 현재 `systemdMinimal`과 `systemd`가 모두 번들됨
  - 둘 중 하나를 제거하려고 하면 다른 빌드 경로가 깨졌음
- 작은 항목들도 더 걷어낼 수 있고, 합산하면 의미 있는 크기가 될 수 있음
- 추가 최적화에는 더 많은 조사와 실험이 필요함

## Comments



### Comment 59998

- Author: neo
- Created: 2026-06-20T10:11:18+09:00
- Points: 1

###### [Lobste.rs 의견들](https://lobste.rs/s/nvfvjt/i_can_haz_smoller_nixos_isos) 
- 딱 이런 용도로 만든 모듈이 있음. 컴파일은 꽤 필요하지만, **NixOS 사용자 공간 전체**를 포함한 완전 독립형 initrd를 zstd 압축 기준 약 80MiB로 만들 수 있음  
  이 작업은 독립형 initrd에만 한정되지 않고, 어떤 NixOS든 용량을 줄이는 데 쓸 수 있음. 설치 ISO에도 아마 적용 가능할 것 같음  
  https://github.com/wucke13/minimal-nixos/

- TinyCore Linux 기본 시스템은 17MB인 **Core**임  
  X와 FLTK/FLWM까지 원하면 23MB인 **TinyCore**이고, 더 많은 창 관리자와 앱까지 원하면 248MB인 **CorePlus**가 있음  
  http://www.tinycorelinux.net/downloads.html
  - 그게 **선언형 설정**이나 재현 가능한 VM과 어떤 관련이 있는지 모르겠음

- NixCon에서 NixOS를 **Yocto 대안**으로 작게 줄인 발표를 추천함: https://youtu.be/AsXY61laNb8  
  기대한 만큼 자세하진 않았지만, 컨퍼런스에서 Óli와 Matthew에게 직접 들은 내용은 굉장했음. 혹시 정리 글이 있는지 궁금함

- NixOS에서 작은 설치 공간을 만들려면 항상 조금 답답함  
  SSH 쪽 크기는 아래 설정으로 줄일 수 있을 것 같음  
  ```nix  
  programs.ssh.setXAuthLocation = false;  
  security.pam.services.su.forwardXAuth = lib.mkForce false;  
  fonts.fontconfig.enable = false;  
  ```  
  `"${nixpkgs}/nixos/modules/profiles/minimal.nix"`도 가져올 수 있음. 거기에 글에서 한 최적화 일부가 들어 있음
  - 원래 글을 쓰게 된 사용 사례에서는 사실 **ssh 자체가 거의 필요 없었음**  
    그래도 대부분의 경우에는 이 방식이 더 합리적일 가능성이 큼  
    `"${nixpkgs}/nixos/modules/profiles/minimal.nix"`는 예전에 보고 기대보다 별로라고 느껴서, 조사를 시작할 때 포함할 생각을 못 했음. 나중에 떠올렸을 때는 이미 절반쯤 진행한 뒤라, 원래 들어갔어야 할 초반에 끼워 넣는 건 조금 정직하지 않게 느껴졌음

- 요즘 시스템에 **Perl**이 끌려 들어오는 경우가 너무 많아서 이상함. 작은 ISO에도 Perl, 뭔가 제대로 된 걸 처음부터 컴파일하려 해도 openssl -> Perl로 이어짐
  - 기본 시스템에서 **Perl 의존성**을 줄이고 더 엄격히 제한하려는 작업이 있음: https://github.com/NixOS/nixpkgs/blob/master/nixos%2Fmodules%2Fprofiles%2Fperlless.nix

- 읽기 전부터, 누가 C로 다시 쓰지 않은 멍청한 **Perl 스크립트** 때문일 거라고 예상함  
  수정: 역시 맞았음

- NixOS는 26.05부터 기본 initrd에서 **systemd**를 사용함. 현대 운영체제가 지원해야 하는 [initrd 사용 사례](https://man7.org/linux/man-pages/man7/bootup.7.html)가 많기 때문임  
  `systemdMinimal`은 더 적은 플래그와 의존성으로 컴파일한 systemd 바이너리라 initrd를 더 작게 유지하는 데 도움이 됨  
  다만 최소 ISO가 목표라면 둘 다 같은 바이너리에 의존하게 만들 수도 있어 보임
