1 पॉइंट द्वारा GN⁺ 4 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • NixOS में सिर्फ कॉन्फ़िगरेशन के आधार पर VM या ISO बनाना आसान है, लेकिन लगभग न्यूनतम live image भी शुरू से ही 458MiB बनती है, जो Alpine VM ISO के लगभग 66MiB से काफी बड़ी है
  • आकार का अधिकांश हिस्सा nix-store.squashfs ले रहा था, और उसके अंदर Python 3.13.13, Linux modules, systemd, Perl, GRUB, दस्तावेज़, और Nix से जुड़ी dependencies शामिल थीं
  • nix.enable = false, documentation.enable = false, और register-nix-paths हटाने के बाद ISO का आकार 458MiB → 384MiB → 360MiB तक घटा, और Boost dependency भी हट गई
  • OpenSSH client, default packages, GRUB installation tools, runtime kernel modules, और Perl-आधारित activation path हटाने के बाद अंतिम आकार 183MiB तक आ गया
  • छोटे experimental boot image के लिए यह उपयोगी संदर्भ हो सकता है, लेकिन इसमें बहुत-सी ज़रूरी सुविधाएँ हट जाती हैं, इसलिए इसे desktop या महत्वपूर्ण environment में सीधे इस्तेमाल करना कठिन है

NixOS कॉन्फ़िगरेशन से ISO बनाना

  • NixOS में कॉन्फ़िगरेशन के आधार पर VM आसानी से बनाया जा सकता है
    • nixos-rebuild build-vm मौजूदा system configuration का VM बनाता है
    • pkgs.nixos का उपयोग करके system configuration न होने पर भी मनचाहा configuration लेकर VM बनाया जा सकता है
  • बुनियादी उदाहरण system.stateVersion = "26.05" और services.getty.autologinUser = "root" के साथ एक न्यूनतम VM बनाता है
  • यह VM thin VM की तरह काम करता है
    • disk image में सिर्फ वही फ़ाइलें जाती हैं जो VM के अंदर सीधे बनाई गई हों
    • /nix/store जैसी बाकी चीज़ें host OS से mount होती हैं
  • अगर host पर Nix नहीं है, या remote host, या सामान्य hypervisor पर चलाना हो, तो self-contained ISO चाहिए
  • NixOS के iso-image.nix module को import करके ISO build किया जा सकता है
    • image.baseName = lib.mkForce "nixos" से output ISO का नाम तय होता है
    • चलाने का उदाहरण qemu-system-x86_64 --cdrom .../nixos.iso -m 1G --accel kvm जैसा है
    • अगर environment amd64 का आधुनिक Linux नहीं है, तो architecture या acceleration method बदलनी पड़ सकती है

शुरुआती बिंदु: 458MiB ISO

  • default ISO build का परिणाम 458MiB था
  • इस image में अभी vim भी शामिल नहीं था
    • boot के बाद vim चलाने पर command not found आता था
  • तुलना के लिए Alpine का VM ISO लगभग 66MiB का था
  • Damn Small Linux का ज़िक्र ऐसे उदाहरण के रूप में आता है, जिसने बहुत छोटे आकार में भी अच्छा desktop environment दिया था
  • लक्ष्य Damn Small Linux के स्तर तक पहुँचना नहीं, बल्कि यह देखना था कि NixOS ISO को कुछ हद तक और छोटा किया जा सकता है या नहीं

ISO के अंदर आकार का विश्लेषण

  • ISO को mount करके du से देखने पर आकार का बँटवारा इस तरह था
    • nix-store.squashfs: 416MiB
    • initrd: 26MiB
    • kernel: 13MiB
    • पूरा ISO: 458MiB
  • आकार का मुख्य कारण मुख्य user space यानी nix-store.squashfs था
  • squashfs को mount करने पर उसके अंदर Nix store जैसी paths दिखाई देती हैं
    • python3-3.13.13: 128MiB
    • linux-6.18.35-modules: 144MiB
    • systemd-260.1: 60MiB
    • perl-5.42.0: 56MiB
    • grub-2.12: कई items मिलाकर लगभग 62MiB
    • nix-manual-2.34.7, nixos-manual-html जैसे दस्तावेज़ भी शामिल थे
  • ISO host पर build होती है, इसलिए ISO के अंदर की store paths को host के /nix/store में भी trace किया जा सकता है
  • nix why-depends से dependency के source की जाँच की गई
    • Boost, Nix daemon path के जरिए शामिल हो रहा था
    • nix-daemon.conf, nix, libnixutil.so के रास्ते boost-1.89.0 तक पहुँचा गया

Nix और दस्तावेज़ हटाना

  • nix.enable = false से image से Nix को हटाने की कोशिश की गई
  • documentation.enable = false से documentation भी बंद की गई
  • पहला परिणाम 458MiB → 384MiB था
  • लेकिन Boost अभी भी बचा हुआ था
    • register-nix-paths.service boot के समय ISO store की contents register करने की कोशिश करता है
    • यही path फिर Nix और Boost को वापस खींच लाता है
  • systemd.services.register-nix-paths = lib.mkForce {} से उस service को खाली करके हटा दिया गया
  • इसके बाद ISO 360MiB का रह गया, और nix why-depends ने पुष्टि की कि Boost dependency नहीं बची

OpenSSH और default packages हटाना

  • इसी तरह environment.defaultPackages को भी खाली किया जा सका
  • ssh हटाना अधिक मुश्किल था
    • modules/programs/ssh.nix OpenSSH को environment.corePackages में जोड़ता है
    • इसे नियंत्रित करने के लिए programs.ssh.enable जैसा विकल्प नहीं मिला
    • services.openssh.enable server configuration है, client हटाने का विकल्प नहीं
  • disabledModules के जरिए programs/ssh.nix को बाहर किया जा सकता था, लेकिन दूसरे modules programs.ssh option के मौजूद होने की अपेक्षा करते थे, जिससे chain errors आने लगे
  • समाधान यह था कि programs.ssh option का उपयोग न करने वाला एक अलग stub option module दिया जाए
    • options.programs.ssh = lib.mkOption {};
    • उसके बाद disabledModules = [ "programs/ssh.nix" ]; से असली SSH module को हटाया गया
  • इस दौरान नीचे की settings भी साथ में लागू की गईं
    • documentation.man.enable = false
    • networking.firewall.enable = false
    • environment.defaultPackages = lib.mkForce []

NixOS module संरचना पर नोट

  • NixOS modules को मोटे तौर पर तीन हिस्सों में बाँटा जा सकता है
    • module-level items: imports, disabledModules
    • option definitions: options.*
    • implementation: config.*
  • जो modules options define नहीं करते, वे config. prefix के बिना implementation properties लिखने वाला संक्षिप्त रूप इस्तेमाल कर सकते हैं
  • बाकी configuration में यही संक्षिप्त रूप बनाए रखने के लिए programs.ssh stub option को अलग import module में रखा गया

GRUB installation tools हटाना

  • बचे हुए बड़े items में से एक लगभग 62MiB के GRUB-संबंधित फ़ाइलें थीं
  • bootloader खुद ज़रूरी है, लेकिन सारे installation tools शामिल करना आवश्यक नहीं माना गया
  • NixOS ISO preset UEFI और BIOS दोनों versions के GRUB को bundle करता है
  • इसे बंद करने का कोई स्पष्ट option नहीं मिला, इसलिए थोड़ा कठोर तरीका अपनाकर इन values को reset किया गया
    • system.extraDependencies = lib.mkForce []
    • environment.systemPackages = lib.mkForce config.environment.corePackages
  • environment.systemPackages को पूरी तरह खाली नहीं किया गया
    • अगर bash न हो, तो getty लगातार crashloop में जा सकता है, इसलिए shell को कुछ हद तक काम करने देने के लिए corePackages रखे गए

kernel modules हटाना

  • linux-6.18.35-modules का आकार 144MiB था, यानी कुल आकार का लगभग एक-चौथाई
  • NixOS में runtime पर इस्तेमाल होने वाले kernel modules को सीमित करने के लिए कोई अच्छा hook नहीं दिखा
  • इसकी जगह system output से kernel-modules फ़ोल्डर हटा दिया गया
    • system.systemBuilderCommands = lib.mkAfter "rm $out/kernel-modules";
  • इस तरीके से runtime module loading लगभग निष्क्रिय हो गई
    • ज़रूरी modules को boot.initrd.kernelModules या availableKernelModules में रखना पड़ेगा
  • इस बदलाव के बाद अधिक सुविधाजनक display resolution पर switch करने की क्षमता खो गई, लेकिन boot होना संभव रहा
  • ISO का आकार 197MiB तक घट गया

Perl हटाना और experimental replacement features

  • अभी भी 56MiB का Perl शामिल था
  • nix why-depends से पता चला कि Perl system activation के दौरान users और /etc configure करने में इस्तेमाल हो रहा था
  • users और /etc configuration को पूरी तरह छोड़ा नहीं जा सकता था
  • इसकी जगह experimental features के जरिए मौजूदा path बदला गया
    • /etc management के लिए overlay method का उपयोग
    • user management के लिए native userborn का उपयोग
  • लागू की गई settings ये थीं
    • system.etc.overlay.enable = true
    • system.etc.overlay.mutable = false
    • services.userborn.enable = true
  • अंतिम ISO आकार 183MiB रह गया

अंतिम स्थिति और सीमाएँ

  • शुरुआती 458MiB से घटकर अंतिम आकार 183MiB तक आ गया, यानी मूल का लगभग एक-तिहाई
  • फिर भी इसे “अच्छा” कहना मुश्किल माना गया
  • वास्तव में इस्तेमाल होने वाले desktop या महत्वपूर्ण environment के लिए यह उपयुक्त नहीं है
    • हटाई गई सभी सुविधाओं के होने के अपने कारण हैं
  • अगर छोटे experimental boot image की ज़रूरत हो और बहुत सीमित काम करना हो, तो यह उपयोगी संदर्भ हो सकता है
  • अंतिम configuration को ज्यों का त्यों कॉपी करके इस्तेमाल करने पर आपके उद्देश्य के लिए ज़रूरी सुविधाएँ गायब हो सकती हैं

और छोटा करने की गुंजाइश

  • इस काम में मुख्य ध्यान उन चीज़ों पर था जिन्हें “बस हटाया जा सकता था” या जिनके लिए अपेक्षाकृत साफ़ replacement उपलब्ध था
  • कुछ ऐसे क्षेत्र अभी भी बचे हैं जहाँ और गहरा काम चाहिए
    • इस समय systemdMinimal और systemd दोनों bundle हो रहे हैं
    • इनमें से किसी एक को हटाने की कोशिश करने पर दूसरी build path टूट जाती थी
  • छोटे-छोटे items भी और हटाए जा सकते हैं, और कुल मिलाकर उनका असर सार्थक हो सकता है
  • आगे की optimization के लिए और अधिक जाँच तथा प्रयोग की आवश्यकता है

1 टिप्पणियां

 
GN⁺ 4 시간 전
Lobste.rs की राय
  • ठीक इसी काम के लिए बना एक मॉड्यूल है। काफ़ी compilation चाहिए, लेकिन पूरा NixOS user space शामिल करने वाला पूरी तरह standalone initrd को zstd compression के साथ लगभग 80MiB तक बनाया जा सकता है
    यह काम सिर्फ standalone initrd तक सीमित नहीं है, बल्कि किसी भी NixOS का आकार घटाने में इस्तेमाल हो सकता है। शायद install ISO पर भी लागू किया जा सकता है
    https://github.com/wucke13/minimal-nixos/

  • TinyCore Linux का बेस सिस्टम 17MB का Core है
    अगर X और FLTK/FLWM भी चाहिए तो 23MB का TinyCore है, और अगर ज़्यादा window managers और apps चाहिएँ तो 248MB का CorePlus है
    http://www.tinycorelinux.net/downloads.html

    • मुझे नहीं पता कि उसका declarative configuration या reproducible VM से क्या लेना-देना है
  • NixCon में NixOS को Yocto alternative के रूप में छोटा करने पर हुई यह talk recommend करूँगा: https://youtu.be/AsXY61laNb8
    यह उतनी detailed नहीं थी जितनी उम्मीद थी, लेकिन conference में Óli और Matthew से सीधे जो सुना वह काफ़ी शानदार था। सोच रहा हूँ क्या इसका कोई write-up है

  • NixOS में छोटा installation footprint बनाना हमेशा थोड़ा frustrating लगता है
    SSH वाली तरफ़ का size नीचे की settings से कम किया जा सकता है

    programs.ssh.setXAuthLocation = false;  
    security.pam.services.su.forwardXAuth = lib.mkForce false;  
    fonts.fontconfig.enable = false;  
    

    "${nixpkgs}/nixos/modules/profiles/minimal.nix" को भी import किया जा सकता है। उसमें post में की गई कुछ optimizations शामिल हैं

    • जिस use case ने असल में मुझे मूल पोस्ट लिखने पर मजबूर किया, उसमें ssh की लगभग ज़रूरत ही नहीं थी
      फिर भी, ज़्यादातर मामलों में यह तरीका ज़्यादा समझदारी भरा हो सकता है
      "${nixpkgs}/nixos/modules/profiles/minimal.nix" मैंने पहले देखा था, लेकिन लगा था कि यह उम्मीद से कम उपयोगी है, इसलिए investigation शुरू करते समय इसे शामिल करने का ख़याल नहीं आया। जब बाद में याद आया, तब तक मैं लगभग आधा काम कर चुका था, इसलिए उसे शुरुआत में होना चाहिए था वहाँ बाद में जोड़ना थोड़ा बेईमानी जैसा लगा
  • आजकल अजीब लगता है कि Perl कितनी बार आधुनिक सिस्टम में खिंचकर आ जाता है। छोटे ISO में भी Perl, और अगर शुरू से कुछ ढंग की चीज़ compile करनी हो तो openssl -> Perl तक बात पहुँच जाती है

    • बेस सिस्टम में Perl dependencies घटाने और उन्हें ज़्यादा सख़्ती से सीमित करने का काम चल रहा है: https://github.com/NixOS/nixpkgs/…
  • पढ़ने से पहले ही लगा था कि वजह कोई बेवकूफ़ी भरा Perl script होगा जिसे किसी ने C में rewrite नहीं किया
    संपादन: हाँ, वही निकला

  • NixOS 26.05 से default initrd में systemd इस्तेमाल करता है। क्योंकि ऐसे कई initrd use cases हैं जिन्हें आधुनिक operating systems को support करना पड़ता है
    systemdMinimal कम flags और dependencies के साथ compile किया गया systemd binary है, इसलिए यह initrd को छोटा रखने में मदद करता है
    लेकिन अगर लक्ष्य minimal ISO है, तो लगता है दोनों को एक ही binary पर depend कराया जा सकता है