Bisakah membuat ISO NixOS yang lebih kecil?
(natkr.com)- NixOS memudahkan pembuatan VM atau ISO hanya dari konfigurasi, tetapi image live yang nyaris minimal pun sejak awal sudah berukuran 458MiB, jauh lebih besar dibanding ISO VM Alpine yang sekitar 66MiB
- Sebagian besar ukuran diambil oleh nix-store.squashfs, yang berisi Python 3.13.13, Linux modules, systemd, Perl, GRUB, dokumentasi, dan dependensi terkait Nix
- Setelah melalui
nix.enable = false,documentation.enable = false, dan penghapusanregister-nix-paths, ukuran ISO turun dari 458MiB → 384MiB → 360MiB, dan dependensi Boost juga hilang - Dengan menyingkirkan klien OpenSSH, paket bawaan, alat instalasi GRUB, modul kernel runtime, dan jalur aktivasi berbasis Perl, ukuran akhir turun hingga 183MiB
- Ini bisa jadi referensi untuk image boot eksperimental berukuran kecil, tetapi karena banyak fungsi penting dihapus, hasilnya sulit dipakai apa adanya untuk desktop atau lingkungan penting
Membuat ISO dari konfigurasi NixOS
- NixOS memudahkan pembuatan VM berbasis konfigurasi
nixos-rebuild build-vmmembuat VM dari konfigurasi sistem saat ini- Dengan
pkgs.nixos, VM juga bisa dibuat dari konfigurasi arbitrer meskipun bukan konfigurasi sistem aktif
- Contoh dasar hanya memakai
system.stateVersion = "26.05"danservices.getty.autologinUser = "root"untuk membuat VM minimal - VM ini bekerja sebagai thin VM
- Image disk hanya berisi file yang dibuat langsung di dalam VM
- Sisanya seperti
/nix/storedimount dari OS host
- Jika host tidak memiliki Nix, atau targetnya host jarak jauh maupun hypervisor umum, maka diperlukan ISO yang self-contained
- Dengan mengimpor modul
iso-image.nixmilik NixOS, ISO bisa dibangunimage.baseName = lib.mkForce "nixos"menentukan nama file ISO keluaran- Contoh menjalankan:
qemu-system-x86_64 --cdrom .../nixos.iso -m 1G --accel kvm - Jika bukan lingkungan Linux modern amd64, arsitektur atau metode akselerasinya mungkin perlu diubah
Titik awal: ISO 458MiB
- Hasil build ISO bawaan berukuran 458MiB
- Image ini bahkan belum menyertakan
vim- Setelah boot, menjalankan
vimmenghasilkancommand not found
- Setelah boot, menjalankan
- Sebagai pembanding, ISO VM Alpine yang disebut berukuran sekitar 66MiB
- Damn Small Linux juga disebut sebagai contoh yang dulu mampu memberi lingkungan desktop yang matang dalam ukuran jauh lebih kecil
- Tujuannya bukan menyamai Damn Small Linux, melainkan melihat apakah ukuran ISO NixOS setidaknya bisa diperkecil sampai batas tertentu
Analisis ukuran di dalam ISO
- Setelah ISO dimount dan diperiksa dengan
du, pembagian ukurannya seperti berikutnix-store.squashfs: 416MiB- initrd: 26MiB
- kernel: 13MiB
- total ISO: 458MiB
- Faktor ukuran utama adalah ruang user-space utama, yaitu
nix-store.squashfs - Saat squashfs dimount, isinya terlihat seperti path di Nix store
python3-3.13.13: 128MiBlinux-6.18.35-modules: 144MiBsystemd-260.1: 60MiBperl-5.42.0: 56MiBgrub-2.12: total beberapa item sekitar 62MiB- Dokumentasi seperti
nix-manual-2.34.7,nixos-manual-html, dan lainnya juga ikut masuk
- Karena ISO dibangun di host, path store di dalam ISO juga bisa ditelusuri dari
/nix/storemilik host - Asal dependensi diperiksa dengan
nix why-depends- Boost masuk melalui jalur Nix daemon
- Rutenya melewati
nix-daemon.conf,nix,libnixutil.so, lalu sampai keboost-1.89.0
Menghapus Nix dan dokumentasi
nix.enable = falsedicoba untuk menghapus Nix itu sendiri dari image- Dokumentasi juga dimatikan dengan
documentation.enable = false - Hasil pertama: 458MiB → 384MiB
- Namun Boost masih tetap ada
register-nix-paths.servicemencoba mendaftarkan isi store ISO saat boot- Jalur ini kembali menarik Nix dan Boost masuk
- Layanan tersebut dikosongkan dan dihapus dengan
systemd.services.register-nix-paths = lib.mkForce {} - Hasilnya ISO menjadi 360MiB, dan
nix why-dependsmengonfirmasi bahwa dependensi Boost sudah hilang
Menghapus OpenSSH dan paket bawaan
- Dengan cara serupa,
environment.defaultPackagesjuga bisa dikosongkan - Penghapusan
sshlebih rumitmodules/programs/ssh.nixmenambahkan OpenSSH keenvironment.corePackages- Tidak ditemukan opsi seperti
programs.ssh.enableuntuk mengendalikannya services.openssh.enableadalah pengaturan server, bukan opsi untuk membuang klien
programs/ssh.nixmemang bisa dikecualikan dengandisabledModules, tetapi modul lain mengasumsikan opsiprograms.sshtetap ada sehingga memicu error berantai- Solusinya adalah menyediakan opsi stub terpisah yang tidak memakai opsi
programs.sshoptions.programs.ssh = lib.mkOption {};- Lalu modul SSH asli dikecualikan dengan
disabledModules = [ "programs/ssh.nix" ];
- Dalam proses ini, pengaturan berikut juga diterapkan
documentation.man.enable = falsenetworking.firewall.enable = falseenvironment.defaultPackages = lib.mkForce []
Catatan tentang struktur modul NixOS
- Modul NixOS secara umum terdiri dari tiga bagian besar
- Item tingkat modul:
imports,disabledModules - Definisi opsi:
options.* - Implementasi:
config.*
- Item tingkat modul:
- Modul yang tidak mendefinisikan opsi bisa memakai bentuk singkat dengan properti implementasi tanpa awalan
config. - Agar bentuk singkat tetap bisa dipakai pada konfigurasi lainnya, opsi stub
programs.sshdipisahkan ke modul impor tersendiri
Menghapus alat instalasi GRUB
- Salah satu item besar yang tersisa adalah file terkait GRUB sekitar 62MiB
- Bootloader itu sendiri masih dibutuhkan, tetapi tidak semua alat instalasinya perlu ikut disertakan
- Preset ISO NixOS membundel GRUB versi UEFI dan BIOS sekaligus
- Karena tidak ada opsi yang jelas untuk mematikannya, dipakai cara yang lebih kasar dengan mereset nilai berikut
system.extraDependencies = lib.mkForce []environment.systemPackages = lib.mkForce config.environment.corePackages
environment.systemPackagestidak dikosongkan total- Tanpa
bash, getty bisa terus crashloop, jadicorePackagestetap dipertahankan agar shell masih bisa berfungsi sampai batas tertentu
- Tanpa
Menghapus modul kernel
linux-6.18.35-modulesberukuran 144MiB, sekitar seperempat dari total ukuran- Di NixOS tidak terlihat ada hook yang baik untuk membatasi modul kernel yang dipakai saat runtime
- Sebagai gantinya, folder
kernel-modulesdihapus dari keluaran sistemsystem.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";
- Cara ini pada dasarnya menonaktifkan pemuatan modul runtime
- Modul yang dibutuhkan harus dimasukkan ke
boot.initrd.kernelModulesatauavailableKernelModules
- Modul yang dibutuhkan harus dimasukkan ke
- Setelah perubahan ini, kemampuan beralih ke resolusi layar yang lebih nyaman hilang, tetapi sistem masih bisa boot
- Ukuran ISO turun lagi menjadi 197MiB
Menghapus Perl dan fitur pengganti eksperimental
- Perl sebesar 56MiB masih ikut terbawa
- Dari
nix why-depends, Perl dipakai saat aktivasi sistem untuk menyusun user dan/etc - Penyusunan user dan
/etctidak bisa dibuang sepenuhnya - Sebagai gantinya, jalur lama diganti dengan fitur eksperimental
- Pengelolaan
/etcmemakai pendekatan overlay - Pengelolaan user memakai userborn native
- Pengelolaan
- Konfigurasi yang diterapkan adalah
system.etc.overlay.enable = truesystem.etc.overlay.mutable = falseservices.userborn.enable = true
- Ukuran ISO akhir menjadi 183MiB
Hasil akhir dan keterbatasan
- Dari titik awal 458MiB, ukuran akhirnya turun menjadi 183MiB, hampir sepertiga dari ukuran awal
- Meski begitu, hasilnya masih sulit disebut “bagus”
- Ini tidak cocok untuk desktop yang benar-benar akan dipakai atau lingkungan penting
- Semua fitur yang dihapus memang ada alasannya
- Jika yang dibutuhkan adalah image boot kecil untuk eksperimen dan hanya menjalankan tugas yang sangat terbatas, hasil ini bisa dijadikan referensi
- Menyalin konfigurasi akhir apa adanya juga berisiko membuat fungsi yang dibutuhkan justru hilang
Peluang pengurangan lebih lanjut
- Pekerjaan kali ini fokus pada hal-hal yang “bisa langsung dibuang” atau punya alternatif yang relatif jelas
- Masih ada area yang butuh pekerjaan lebih dalam
- Saat ini
systemdMinimaldansystemdsama-sama dibundel - Saat mencoba membuang salah satunya, jalur build lain justru rusak
- Saat ini
- Item-item kecil lainnya juga masih bisa terus dibersihkan, dan jika dijumlahkan ukurannya bisa tetap berarti
- Optimalisasi tambahan masih memerlukan lebih banyak riset dan eksperimen
1 komentar
Komentar Lobste.rs
Ada modul yang dibuat tepat untuk kegunaan seperti ini. Memang perlu cukup banyak kompilasi, tetapi bisa membuat initrd mandiri sepenuhnya yang mencakup seluruh user space NixOS menjadi sekitar 80MiB dengan kompresi zstd
Pekerjaan ini tidak terbatas hanya pada initrd mandiri, dan bisa dipakai untuk mengurangi ukuran NixOS apa pun. Mungkin juga bisa diterapkan pada ISO instalasi
https://github.com/wucke13/minimal-nixos/
Sistem dasar TinyCore Linux adalah Core berukuran 17MB
Jika ingin X dan FLTK/FLWM juga, ada TinyCore berukuran 23MB, dan jika ingin lebih banyak window manager serta aplikasi, ada CorePlus berukuran 248MB
http://www.tinycorelinux.net/downloads.html
Saya merekomendasikan presentasi di NixCon tentang mengecilkan NixOS sebagai alternatif Yocto: https://youtu.be/AsXY61laNb8
Tidak sedetail yang saya harapkan, tetapi apa yang saya dengar langsung dari Óli dan Matthew di konferensi sangat mengesankan. Saya penasaran apakah ada tulisan rangkumannya
Di NixOS, rasanya selalu agak frustrasi saat mencoba membuat jejak instalasi yang kecil
Ukuran bagian SSH sepertinya bisa dikurangi dengan pengaturan berikut
"${nixpkgs}/nixos/modules/profiles/minimal.nix"juga bisa di-import. Di situ sudah ada sebagian optimasi yang disebut di tulisanMeski begitu, dalam kebanyakan kasus pendekatan ini kemungkinan lebih masuk akal
"${nixpkgs}/nixos/modules/profiles/minimal.nix"pernah saya lihat sebelumnya dan terasa kurang memuaskan dibanding harapan, jadi saya tidak terpikir untuk memasukkannya saat mulai menyelidiki. Ketika saya teringat lagi belakangan, pekerjaan saya sudah setengah jalan, jadi rasanya agak tidak jujur untuk menyelipkannya ke tahap awal yang seharusnya memang memasukkannya sejak awalAneh sekali bahwa Perl terlalu sering ikut tertarik masuk ke sistem modern. Bahkan untuk ISO kecil pun ada Perl, dan saat mencoba mengompilasi sesuatu yang layak dari awal pun jadinya openssl -> Perl
Bahkan sebelum membaca, saya menduga ini gara-gara skrip Perl bodoh yang belum ditulis ulang ke C
Edit: ternyata benar
Mulai 26.05, NixOS menggunakan systemd di initrd bawaan. Alasannya karena ada banyak kasus penggunaan initrd yang perlu didukung sistem operasi modern
systemdMinimaladalah biner systemd yang dikompilasi dengan lebih sedikit flag dan dependensi, sehingga membantu menjaga ukuran initrd tetap kecilNamun, jika targetnya adalah ISO minimal, tampaknya keduanya juga bisa dibuat bergantung pada biner yang sama