- NixOS, yalnızca yapılandırmayla VM veya ISO oluşturmayı kolaylaştırıyor; ancak neredeyse en küçük canlı imaj bile baştan 458MiB olarak üretiliyor ve Alpine VM ISO’sunun yaklaşık 66MiB boyutuna kıyasla büyük fark gösteriyor
- Boyutun büyük kısmını nix-store.squashfs oluşturuyordu; bunun içinde Python 3.13.13, Linux modülleri, systemd, Perl, GRUB, belgeler ve Nix ile ilgili bağımlılıklar yer alıyordu
nix.enable = false,documentation.enable = false,register-nix-pathskaldırma adımlarından geçilince ISO boyutu 458MiB → 384MiB → 360MiB oldu ve Boost bağımlılığı da çıktı- OpenSSH istemcisi, varsayılan paketler, GRUB kurulum araçları, çalışma zamanı çekirdek modülleri ve Perl tabanlı etkinleştirme yolu da kaldırılınca nihai boyut 183MiB seviyesine indi
- Küçük deneysel önyükleme imajları için faydalı bir referans olabilir; ancak gerekli birçok özelliği çıkardığı için masaüstünde veya önemli ortamlarda olduğu gibi kullanmak zor
NixOS yapılandırmasından ISO oluşturma
- NixOS, yapılandırma temelinde kolayca VM oluşturabiliyor
nixos-rebuild build-vm, mevcut sistem yapılandırmasının VM’sini üretirpkgs.nixoskullanılırsa sistem yapılandırması olmasa da rastgele bir yapılandırmayla VM oluşturulabilir
- Temel örnek, yalnızca
system.stateVersion = "26.05"veservices.getty.autologinUser = "root"bırakan en minimal VM’yi oluşturuyor - Bu VM, thin VM olarak çalışıyor
- Disk imajına yalnızca VM içinde doğrudan oluşturulan dosyalar giriyor
/nix/storeve geri kalan kısımlar ana makine işletim sisteminden mount ediliyor
- Ana makinede Nix yoksa ya da uzak ana makinede, sıradan bir hypervisor üzerinde çalıştırılacaksa kendi kendine yeterli bir ISO gerekiyor
- NixOS’un
iso-image.nixmodülü import edilirse ISO derlenebiliyorimage.baseName = lib.mkForce "nixos"ile çıktı ISO adını belirliyor- Çalıştırma örneği
qemu-system-x86_64 --cdrom .../nixos.iso -m 1G --accel kvmbiçiminde - Ortam amd64 için modern bir Linux değilse mimariyi veya hızlandırma yöntemini değiştirmek gerekebilir
Başlangıç noktası: 458MiB ISO
- Varsayılan ISO derleme sonucu 458MiB idi
- Bu imajda henüz
vimbile yok- Önyüklemeden sonra
vimçalıştırıldığındacommand not foundçıkıyor
- Önyüklemeden sonra
- Karşılaştırma için verilen Alpine VM ISO’su yaklaşık 66MiB
- Damn Small Linux, çok daha küçük boyutta tamamlanmış bir masaüstü ortamı sunmuş bir örnek olarak anılıyor
- Amaç Damn Small Linux seviyesine ulaşmak değil, NixOS ISO’sunun ne kadar küçültülebileceğini görmek
ISO iç boyut analizi
- ISO mount edilip
duile bakıldığında boyut şu şekilde ayrılıyordunix-store.squashfs: 416MiB- initrd: 26MiB
- kernel: 13MiB
- toplam ISO: 458MiB
- Asıl boyut etkeni, ana kullanıcı alanı olan
nix-store.squashfsidi - squashfs mount edildiğinde içinde Nix store’a benzeyen yollar görülüyor
python3-3.13.13: 128MiBlinux-6.18.35-modules: 144MiBsystemd-260.1: 60MiBperl-5.42.0: 56MiBgrub-2.12: birkaç kalemin toplamında yaklaşık 62MiBnix-manual-2.34.7,nixos-manual-htmlgibi belgeler de dahil
- ISO ana makinede derlendiği için, ISO içindeki store yolları ana makinenin
/nix/storedizininde de izlenebiliyor nix why-dependsile bağımlılıkların kaynağı incelendi- Boost, Nix daemon yolu üzerinden geliyordu
nix-daemon.conf,nix,libnixutil.soüzerindenboost-1.89.0’a ulaşılıyordu
Nix ve belgeleri kaldırma
nix.enable = falseile imajdan Nix’in kendisini çıkarmaya çalışıldıdocumentation.enable = falseile belgeler de devre dışı bırakıldı- İlk sonuç 458MiB → 384MiB oldu
- Ancak Boost hâlâ kalmıştı
register-nix-paths.service, önyüklemede ISO store içeriğini kaydetmeye çalışıyordu- Bu yol yeniden Nix ve Boost’u içeri çekiyordu
systemd.services.register-nix-paths = lib.mkForce {}ile bu servis boşaltılıp kaldırıldı- Sonuçta ISO 360MiB oldu ve
nix why-dependsçıktısında Boost bağımlılığının kalmadığı doğrulandı
OpenSSH ve varsayılan paketleri kaldırma
- Benzer şekilde
environment.defaultPackagesde boşaltılabildi sshkaldırmak daha zordumodules/programs/ssh.nix, OpenSSH’yienvironment.corePackagesiçine ekliyordu- Bunu kontrol edecek
programs.ssh.enablegibi bir seçenek bulunamadı services.openssh.enablebir istemci kaldırma seçeneği değil, sunucu ayarıydı
disabledModulesileprograms/ssh.nixdışlanabiliyordu; ancak diğer modüllerprograms.sshseçeneğinin varlığını beklediği için zincirleme hatalar oluşuyordu- Çözüm,
programs.sshseçeneklerini kullanmayan ayrı bir modül olarak stub seçeneği sunmaktıoptions.programs.ssh = lib.mkOption {};- Ardından
disabledModules = [ "programs/ssh.nix" ];ile gerçek SSH modülü dışlandı
- Bu süreçte şu ayarlar da birlikte uygulandı
documentation.man.enable = falsenetworking.firewall.enable = falseenvironment.defaultPackages = lib.mkForce []
NixOS modül yapısı notu
- NixOS modülleri kabaca üç bölümden oluşur
- Modül düzeyi öğeler:
imports,disabledModules - Seçenek tanımları:
options.* - Uygulama:
config.*
- Modül düzeyi öğeler:
- Seçenek tanımlamayan modüller,
config.öneki olmadan uygulama özelliklerini yazan kısaltılmış biçimi kullanabilir - Kalan yapılandırmada bu kısaltılmış biçimi korumak için
programs.sshstub seçeneği ayrı bir import modülüne ayrıldı
GRUB kurulum araçlarını kaldırma
- Kalan büyük kalemlerden biri, yaklaşık 62MiB tutan GRUB ile ilgili dosyalardı
- Önyükleyicinin kendisi gerekliydi; ancak tüm kurulum araçlarını dahil etmek gerekmiyordu
- NixOS ISO preset’i hem UEFI hem BIOS sürümü GRUB’u paket halinde getiriyor
- Bunu kapatmak için net bir seçenek olmadığı için daha sert bir yöntemle şu değerler sıfırlandı
system.extraDependencies = lib.mkForce []environment.systemPackages = lib.mkForce config.environment.corePackages
environment.systemPackagestamamen boşaltılmadıbasholmazsa getty sürekli crashloop’a girebileceğinden, kabuğun bir miktar çalışması içincorePackageskorundu
Çekirdek modüllerini kaldırma
linux-6.18.35-modules144MiB idi ve toplam boyutun yaklaşık dörtte birine denk geliyordu- NixOS’ta çalışma zamanında kullanılacak çekirdek modüllerini sınırlamak için uygun bir hook görünmüyordu
- Bunun yerine sistem çıktısından
kernel-modulesklasörü kaldırıldısystem.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";
- Bu yöntem çalışma zamanında modül yüklemeyi fiilen devre dışı bırakıyor
- Gerekli modüllerin
boot.initrd.kernelModulesveyaavailableKernelModulesiçine eklenmesi gerekiyor
- Gerekli modüllerin
- Bu değişiklikten sonra daha rahat bir ekran çözünürlüğüne geçme özelliği kaybedildi ama sistem yine de önyükleyebildi
- ISO boyutu 197MiB seviyesine indi
Perl’i kaldırma ve deneysel alternatif özellikler
- Hâlâ 56MiB boyutunda Perl bulunuyordu
nix why-dependsile bakıldığında Perl’in sistem etkinleştirme sırasında kullanıcıları ve/etciçeriğini oluşturmak için kullanıldığı görüldü- Kullanıcı yönetimi ve
/etcyapılandırması tamamen terk edilemedi - Bunun yerine mevcut yol deneysel özelliklerle değiştirildi
/etcyönetiminde overlay yöntemi kullanıldı- Kullanıcı yönetiminde yerel userborn kullanıldı
- Uygulanan ayarlar şunlardı
system.etc.overlay.enable = truesystem.etc.overlay.mutable = falseservices.userborn.enable = true
- Nihai ISO boyutu 183MiB oldu
Son durum ve sınırlamalar
- Başlangıçtaki 458MiB boyuttan nihai 183MiB boyuta inildi; yani neredeyse özgün boyutun üçte biri seviyesine düşüldü
- Yine de sonuç “iyi” olarak görülmüyor
- Gerçekten kullanılacak bir masaüstü ya da kritik ortam için uygun değil
- Kaldırılan özelliklerin hepsinin bir varlık nedeni var
- Küçük deneysel önyükleme imajına ihtiyaç duyuluyorsa ve yalnızca çok küçük işler yapılacaksa faydalı olabilir
- Nihai yapılandırmayı doğrudan kopyalayıp kullanmak, amaç için gerekli bazı işlevlerin eksik kalmasına yol açabilir
Daha da küçültme payı
- Bu çalışmada, “basitçe kaldırılabilen” ya da nispeten açık alternatifleri olan öğelere odaklanıldı
- Daha derin çalışma gerektiren alanlar hâlâ var
- Şu anda hem
systemdMinimalhemsystemdbirlikte paketleniyor - Bunlardan birini kaldırmaya çalışınca başka derleme yolları bozuldu
- Şu anda hem
- Daha küçük kalemler de ayrıca temizlenebilir ve toplamda anlamlı bir boyut tasarrufu sağlayabilir
- Ek optimizasyon için daha fazla araştırma ve deney gerekiyor
1 yorum
Lobste.rs görüşleri
Tam bu amaç için yapılmış bir modül var. Epey derleme gerektiriyor ama tüm NixOS kullanıcı alanını içeren tamamen bağımsız bir initrd’yi zstd sıkıştırmayla yaklaşık 80MiB boyutunda üretebiliyor
Bu çalışma yalnızca bağımsız initrd ile sınırlı değil; herhangi bir NixOS’un boyutunu küçültmek için de kullanılabilir
Kurulum ISO’suna da muhtemelen uygulanabilir gibi görünüyor
https://github.com/wucke13/minimal-nixos/
TinyCore Linux’un temel sistemi 17MB boyutundaki Core
X ve FLTK/FLWM de istenirse 23MB boyutundaki TinyCore var; daha fazla pencere yöneticisi ve uygulama istenirse 248MB boyutundaki CorePlus bulunuyor
http://www.tinycorelinux.net/downloads.html
NixCon’da NixOS’un Yocto alternatifi olarak küçültülmesini anlatan şu sunumu tavsiye ederim: https://youtu.be/AsXY61laNb8
Beklediğim kadar ayrıntılı değildi ama konferansta Óli ve Matthew’dan bizzat duyduklarım gerçekten etkileyiciydi. Acaba bununla ilgili bir yazılı özet var mı diye merak ediyorum
NixOS’ta küçük bir kurulum alanı oluşturmak her zaman biraz sinir bozucu
SSH tarafındaki boyut şu ayarlarla azaltılabilir gibi görünüyor
"${nixpkgs}/nixos/modules/profiles/minimal.nix"da içe aktarılabilir. Yazıdaki optimizasyonların bir kısmı orada zaten varYine de çoğu durumda bu yaklaşım muhtemelen daha mantıklı olur
"${nixpkgs}/nixos/modules/profiles/minimal.nix"dosyasına daha önce bakmıştım ve beklediğim kadar iyi olmadığını düşündüğüm için araştırmaya başlarken onu dahil etmeyi akıl etmedim. Sonradan aklıma geldiğinde ise işin zaten yarısına gelmiştim; aslında en başta yer alması gereken bir şeyi sonradan araya sıkıştırmak biraz dürüstçe gelmediBu aralar Perl’ün modern sistemlere çok sık dahil edilmesi garip geliyor. Küçük ISO’da da Perl var; sıfırdan düzgün bir şey derlemeye çalışınca bile zincir openssl -> Perl’e gidiyor
Okumadan önce bile bunun, birinin C’de yeniden yazmadığı aptal bir Perl betiği yüzünden olacağını tahmin etmiştim
Düzeltme: tahminim doğru çıktı
NixOS, 26.05 sürümünden itibaren varsayılan initrd’de systemd kullanıyor. Çünkü modern bir işletim sisteminin desteklemesi gereken pek çok initrd kullanım senaryosu var
systemdMinimal, daha az bayrak ve bağımlılıkla derlenmiş bir systemd ikilisi; bu da initrd’yi daha küçük tutmaya yardımcı oluyorAncak hedef minimum ISO ise, ikisinin de aynı ikiliye bağımlı olmasını sağlamak da mümkün gibi görünüyor