- Railway ने user code से container image बनाने वाले builder को फिर से design किया है, और 1.4 करोड़ से ज़्यादा apps build करने के Nixpacks अनुभव को Railpack में लाया है
- Nixpacks 80% users के लिए पर्याप्त था, लेकिन बाकी 2 लाख Railway users version management, image size और caching की सीमाओं से टकरा सकते थे
- Railpack, Nix के commit-based version management की जगह
major.minor.patchversions, dependency locking और Mise-based installation flow के जरिए build reproducibility बढ़ाता है - BuildKit LLB और Frontend सीधे generate करने से default Node image 38% और default Python image 77% छोटी हो गई, और environments के बीच share हो सकने वाला cache भी संभव हुआ
- Railpack अभी Beta में है और service settings से enable किया जा सकता है; Railway व्यापक language support के बजाय पहले अक्सर इस्तेमाल होने वाली languages की maturity बढ़ा रहा है
Railway ने नया builder क्यों बनाया
- Railway ने Railpack को Railway builder के अगले चरण के रूप में पेश किया
- Railpack को Nixpacks से 1.4 करोड़ से ज़्यादा apps build करने के अनुभव के आधार पर शुरू से नया develop किया गया
- Nixpacks लगभग 3 साल पहले जारी होने के बाद Railway में user code से images build करने का default तरीका बन गया
- यह कुल users में से 80% के लिए अच्छा काम करता था, लेकिन बाकी 2 लाख Railway users को सीमाओं का सामना करना पड़ सकता था
- Railway ने माना कि user base को 10 लाख से 10 करोड़ तक बढ़ाने के लिए builder को बड़े स्तर पर upgrade करना जरूरी है
Nixpacks को Nix में जिन सीमाओं का सामना करना पड़ा
- सबसे बड़ी समस्या Nix का commit-based package version management था
- हर package में केवल latest major version उपलब्ध होता है
- version nixpkgs repo के किसी specific commit से बंधा होता है
- सभी patch versions को support करने की कोशिश version string और commit SHA को सीधे map करने वाली structure बन गई, जो Nix version management से परिचित न होने वाले contributors के लिए स्पष्ट या maintain करना आसान नहीं था
- Node और Python जैसी languages में अंततः केवल latest major version ही support हो पाया
- latest package versions support करने के लिए commit SHA update करने पर दूसरे package versions भी साथ में बदल सकते थे
- default version बदलने पर पहले काम कर रहे user builds के अचानक error से fail होने की संभावना बढ़ जाती थी
- Railway के लिए users का latest packages तक access न होना उतना बुरा नहीं था, जितना सफल build का अचानक टूट जाना
Image size और caching की समस्याएं
- Nixpacks जिस तरह Nix से dependencies लाता था, वह अक्सर बड़ी image size बनाता था
- build और runtime के लिए जरूरी Nix और संबंधित packages/libraries एक ही
/nix/storelayer में चले जाते थे - Nix dependencies को अलग layers में बांटने का तरीका न होने से final image size घटाने की सीमा थी
- Railway इसे Nix की अपनी समस्या नहीं, बल्कि Nixpacks में Nix इस्तेमाल करने के तरीके की समस्या मानता है
- caching में भी यह control करना मुश्किल था कि layer cache कब invalidate होगा
- Railway हर build में deployment ID environment variable inject करता है
- Dockerfile में यह variable जुड़ने के बाद चलने वाली layers हमेशा invalidate हो जाती थीं और cache नहीं हो सकती थीं
- Nix के core elements को users से छिपाने वाला approach भी ठीक नहीं बैठा
- वे चाहते थे कि users को यह समझने की जरूरत न पड़े कि derivation क्या है, या Node 22.14.0 unstable channel के किसी specific archive version में क्यों है
Railpack के structural बदलाव
- Railway ने Nixpacks में आई समस्याओं को हल करने के लिए Railpack बनाया
- Nix से हटते हुए नाम भी Nixpacks से Railpack हो गया
- BuildKit libraries के कारण codebase Rust से Go में बदला गया
- Railpack final image generation को ज्यादा directly control करता है
- BuildKit LLB और Frontend सीधे generate करता है
- Nixpacks की तुलना में default Node image 38% और default Python image 77% छोटी हो गई
- version resolution और अधिकांश package installation के लिए Mise का इस्तेमाल करता है
- भविष्य में दूसरे executable sources support करने की गुंजाइश भी छोड़ता है
- सफल build में इस्तेमाल की गई dependencies को lock किया जा सकता है
- default Node version 22 से 24 हो जाने पर भी build टूटने से बचाया जा सकता है
- BuildKit secrets का इस्तेमाल करके secret environment variables को build logs या final image में दिखने से रोकता है
Railpack build कैसे काम करता है
- Railpack process तीन चरणों में बंटा है
- Analyze: code देखकर install किए जाने वाले packages, चलाए जाने वाले commands और start command तय करता है
- Plan: कई stages से बना JSON-serializable build plan बनाता है, जहां हर stage दूसरे stages या पूरी image से input लेता है
- Generate: plan के inputs और outputs के अनुसार BuildKit build graph बनाता है
- Dockerfile linear होता है, लेकिन BuildKit graph कहीं ज्यादा parallel ढंग से बना होता है
- हर command multi-stage build के अपने stage में चलता है, जिससे input layers और final file system assemble करने के तरीके पर बारीक control मिलता है
- Railpack सभी जरूरी build steps वाला build plan generate करता है
- हर stage जरूरी previous stages या images को खास तौर पर define करता है
- यह format Nixpacks में इस्तेमाल हुए तरीके से ज्यादा low-level है
- plan को LLB format graph में बदलकर interpret किया जाता है
- BuildKit अंत से शुरू कर पीछे की ओर काम करता है, संभव होने पर cache से लेता है, और जरूरत पड़ने पर ही commands चलाकर requested layer resolve करता है
- किसी specific environment variable के बदलने पर layer invalidate करने के लिए Railpack इस्तेमाल किए गए variable values को hash करता है, और उस hash वाली file को input file system में mount करता है
- अगर code और इस्तेमाल किए गए variables नहीं बदलते, तो layer cache hit होता है
- Railpack image बनने के तरीके को पूरी तरह define कर सकता है
Railpack से संभव हुए काम
- Vite, Astro, CRA, Angular static sites को zero-config में build और deploy किया जा सकता है
- build और Railway UI के बीच integration ज्यादा tight हो गया है
- Railpack release के बिना भी language के latest versions support किए जा सकते हैं
- project के कई environments में optimized layer caching इस्तेमाल की जा सकती है
अभी इस्तेमाल करने का तरीका और support scope
- Railpack अभी Beta में उपलब्ध है और service settings से activate किया जा सकता है
- इसे पहले से railway.com और central station builds में इस्तेमाल किया जा रहा है
- फिलहाल support में ये शामिल हैं
- Node
- Python
- Go
- PHP
- Static HTML deployment
- Vite, Astro, CRA, Angular static sites का basic support
- Railway का लक्ष्य ऐसा environment बनाना है जहां frontend और backend दोनों आसानी से deploy किए जा सकें
- framework और language support लगातार जोड़ा जा रहा है
- requests Help Station पर ली जा सकती हैं
- core API और abstractions तय होने तक, व्यापक support के बजाय ज्यादा इस्तेमाल होने वाली languages में depth को प्राथमिकता दी जा रही है
- Railpack open source है और documentation railpack.com पर उपलब्ध है
1 टिप्पणियां
Hacker News की राय
मैं Nix का प्रशंसक हूं, लेकिन Railway के Nix से दूर जाने की आलोचना नहीं करना चाहता। बस कुछ शिकायतों को और स्पष्टीकरण की जरूरत लगती है
Nixpkgs शानदार है, लेकिन यह Nix के समान नहीं है, और अगर आप toolchain का कोई मनचाहा version लाना चाहते हैं तो Nixpkgs आदर्श नहीं है। Rust का मनचाहा version लाने वाले Nix tools पहले से ही बहुत अच्छे हैं, और दूसरे Nix-आधारित development tools ने भी दिखाया है कि इसे अच्छी तरह कैसे संभाला जा सकता है
“Nix dependencies को अलग layer में बांटने का कोई तरीका नहीं है” यह बात भी समझ नहीं आती। आप जैसे चाहें वैसे बांट सकते हैं, और Nixpkgs के built-in Docker tools में भी इसका कुछ support है
Rust से Go पर जाना सीधे Nix से जुड़ा नहीं है, लेकिन दिलचस्प है, और ऐसा भी लगता है जैसे Railpacks और Nixpacks अलग-अलग लोगों ने बनाए हों। मैंने देखा है कि जब Nix से परिचित न होने वाले लोग संगठन के अंदर किसी अधूरे Nix solution को संभाल लेते हैं तो काफी खराब स्थिति बनती है, इसलिए workplace में आमतौर पर ऐसी स्थिति बनने के डर से Nix इस्तेमाल नहीं करता
“जैसे चाहें वैसे layers बांट लें” में भी अहम बात यह है कि क्या वह स्पष्ट, सरल और default behavior है
लोग Nix से इसलिए नाराज नहीं हैं कि यह Turing-complete नहीं है, बल्कि इसलिए कि यह उस ecosystem के idiomatic projects के साथ सीधे फिट होने वाली सरल first-class API नहीं देता, जिससे यह जितनी समस्याएं हल करता है उससे ज्यादा समस्याएं पैदा कर देता है
अगर Nix इस्तेमाल करने वाले हर project का अंत Nix की समस्याएं ठीक करने के लिए खुद modules लिखने में होता है, तो अच्छी documentation वाले mainstream tools के बजाय Nix इस्तेमाल करने की वजह कमजोर है। इस मामले में भी ठीक वही दिख रहा है, और ज्यादातर लोग शायद बस Docker चुनेंगे
developers के लिए बने product का व्यावहारिक developer experience समस्याओं को geologic time scale के बजाय तेज गति से हल करने की जगह वैचारिक रूप से शुद्ध flakes से चिपके रहना निराशाजनक है। मुझे पता है कि यह voluntary contribution है, लेकिन खराब user experience के कारण practically इस्तेमाल कठिन हो जाने वाली चीजों में इतनी ज्यादा technical मेहनत लगना बहुत अफसोसजनक है
Nix जिस तरह Nixpkgs structure के साथ काम करता है, उसमें किसी package version को pin करने का मतलब पूरे nixpkgs tree के commit को pin करना होता है। node/python/ruby package builds, package directory के बाहर tree की state पर भी निर्भर करते हैं, इसलिए version और commit के बीच mapping की जरूरत पड़ती है
यह abstraction leak करती है, इसलिए Railway को इसे users के सामने लाना पड़ता है, और user तो बस
yarn add new-fancy-nodejs-package-with-linked–native-depsकरना चाहता था, लेकिन उसे nixpkgs repository की कई states को मिलाने की स्थिति से जूझना पड़ सकता हैसीमित scope वाले use case में Nix को Nixpkgs के बिना इस्तेमाल करना ठीक हो सकता है, लेकिन Railway जैसे platform पर इसे justify करना मुश्किल दिखता है
pkgआमतौर पर ठीक काम करता था, लेकिन एक दिन ports से vim को custom USE flags के साथ compile करने की कोशिश की, तो 20 से ज्यादा dependencies आ गईं और हरmake menuconfigपर options पूछे गए, फिर 23 में से 16वां package “इसके लिए वह चाहिए, और उसके लिए Fubar3.32.1 चाहिए, लेकिन Fubar3 तो Fubar4 से deprecated हो चुका है” जैसी बात कहकर fail हो गया, तो मैंने हार मान लीसमझता हूं कि Core OS developers 10,000 से ज्यादा packages को सब support नहीं कर सकते, लेकिन यह भी साफ करना चाहिए कि अगर असल में custom features enable करके इस्तेमाल करने की कोशिश करें तो failure की संभावना ज्यादा है। या फिर ports में आने से पहले स्वतंत्र रूप से बनाए गए standard build का सफल होना criterion होना चाहिए, और जो compile नहीं होते उन्हें ports list से हटा देना बेहतर है
Nix language की घंटों आलोचना की जा सकती है, लेकिन यह पुरानी है, उस समय अपनी तरफ से best effort थी, और अब शायद इसे बदलने का value बहुत बड़ा नहीं है। Nix build system काफी primitive लगता है, और अक्सर वे चीजें भी फिर से build करता है जिन्हें फिर से build करने की जरूरत नहीं लगती। उदाहरण के लिए NixOS install ISO के build का बड़ा हिस्सा kernel को दी जाने वाली command line
console=ttyS2,1500000n8पर depend करता है, इसलिए सिर्फ serial port speed बदलने पर भी करीब 3 मिनट का build चाहिए। यह हास्यास्पद है, लेकिन इसकी वजह से मैं Nix छोड़ूंगा नहीं; बस अपनी builds में ऐसा allow नहीं करूंगाDocker images के लिए Nix, मेरी नजर में वह क्षेत्र है जहां Nix सबसे कमजोर है। बहुत पहले Go software बनाते समय container image में Postgres का
pg_dumpbinary जोड़ना पड़ा था। infrastructure team के सुझाव पर Nix इस्तेमाल किया तो compressed Go binary वाली 50MB image किसी अज्ञात वजह से 1.5GB हो गई।pg_dump464KB है। आखिर में Bazel औरrules_debianसे apt package install किया, और distroless पर image कहीं ज्यादा साफ और छोटी हो गई। वास्तविक Nix experience के आधार पर लगता है कि Nix system हमेशा 1.4GB का बन जाता है। install ISO भी 1.4GB, नई install की गई machine भी 1.4GBबड़े C++ project को build करना चाहने की स्थिति पहले से ही अच्छी तरह paved path है, और C++ को Rust से बदल देने पर मूल बात नहीं बदलती। ऐसे build systems हैं जो library situation को कम दर्दनाक बनाते हैं, और वे भी Nix जितने complex हैं, लेकिन इस use case के लिए कुछ ज्यादा fit भी हैं। Nix दूसरे लोगों के software और nixpkgs को build करने वाला build system बनने की कोशिश करता है, इसलिए यह बहुत general जगह पर बैठता है। अपने software को build करने के लिए design किए गए build systems आमतौर पर उस काम को बेहतर करते हैं। व्यक्तिगत तौर पर मैं Bazel से संतुष्ट हूं और Go-only projects के
go buildके अलावा शायद ही कुछ और इस्तेमाल करूं, लेकिन options बहुत हैं। 99% मामलों में Nix की जगह उन्हीं का इस्तेमाल करें, और ताकि लोग home-manager से latest version install कर सकें, एक flake लिख देंversion चुनने वाला हिस्सा अजीब लगता है। nixpkgs का version किसी system को चलाते या build करते समय तो समझ आता है, लेकिन अगर आप platform के रूप में runtime या compiler दे रहे हैं, तो devenv की तरह version सीधे उपलब्ध कराने का तरीका चाहिए
पुराने nodejs देने के लिए अगर पुराना system build करना पड़े, तो dependencies के security patches छूट जाते हैं। Devenv इसे, उदाहरण के लिए, https://github.com/cachix/nixpkgs-python से “सभी Python versions को Nix में हर घंटे up-to-date रखना” जैसे तरीके से संभालता है
Railway का हर build में deployment ID environment variable inject करना installation के अगले layer में भी किया जा सकता था। packages को कई layers में बांटा भी जा सकता है, और layers की संख्या घटाने के लिए bundle-level automation भी है
“Nix में खुद समस्या नहीं है, समस्या हमारे इस्तेमाल करने के तरीके में थी” सही tool को सही काम में इस्तेमाल करें का अच्छा उदाहरण है। Nix कुछ use cases के लिए शानदार है और कुछ के लिए बेहद खराब
समस्या यह है कि Nix की learning curve इतनी ज्यादा है कि जब तक आप इतना समझते हैं कि फैसला कर सकें, तब तक आप इतना समय लगा चुके होते हैं कि वापस लौटना अफसोसजनक लगता है, और अपनी मूल जरूरत हल करने के लिए उसे जबरन fit करने लगते हैं
इसी paradigm की वजह से AI के लिए specification के मुताबिक
shell.nixयाconfiguration.nixबनाना बहुत आसान है। जैसे इसमें Python packages, Linux packages, environment variables, path items वगैरह हो सकते हैंrepository में उस package को पूरी तरह support करने वाला environment शामिल करने के लिए मैं ऐसी चीजें अक्सर इस्तेमाल करता हूं। flakes इस्तेमाल करने से यह ज्यादा reproducible होगा, लेकिन मेरी समझ में
flake.nix, version pinning वालेshell.nixजैसा है और मैं अभी भी सीख रहा हूंऐसा लगता है जैसे जहां version नहीं है, वहां जबरन version ठूंसने की कोशिश की जा रही है। यह square cube को round hole में डालने जैसा है
“default version” उस पर depend करने वाली चीजों को तोड़ देता है—इसका मतलब क्या है, समझ नहीं आता। यह Docker का
:latesttag इस्तेमाल करने जैसा है, और फिर हर बार नया server शुरू होने पर उसके पिछले “default” image से अलग version होने की वजह से टूटने पर हैरान होनाइस blog post की व्याख्या मुझे बिल्कुल समझ नहीं आती। ऐसा लगता है जैसे इन्हें software का “version” क्या होता है, यह बिल्कुल नहीं पता
“Nix dependencies को अलग layers में बांटने का कोई तरीका नहीं है” भी क्यों, यह समझ नहीं आता। जाहिर है
/nix/storeको जितनी जरूरत हो उतनी layers में बांटा जा सकता है। शक होता है कि इन्हें containers और Nix का इस्तेमाल शुरू से करना भी आता है या नहींऐसी साफ अपरिपक्वता देखकर यह हैरानी की बात नहीं कि उनके सुझाए solution से भी सड़ी मछली जैसी बू आती है। यह typical NIH syndrome है, और बहुत संभव है कि जिन समस्याओं को वे Nix से हल नहीं कर पाए, वही नई “solution” में भी फैल जाएं
जैसा दूसरे लोगों ने कहा, nix2container और flakes शायद उनकी सारी समस्याएं हल कर देंगे
version management की बात करें तो 3 साल पहले लिखे गए flakes आज भी बिल्कुल उन्हीं versions और उसी output के साथ build होते हैं, जैसे पहली बार लिखते समय होते थे
हालांकि सुनने में ऐसा लगता है जैसे platform के रूप में market में जाकर funding raise करनी है
edit: अभी nixpacks का GitHub देखा, और तुरंत दिखा कि वे oxalica का rust-overlay[0] नहीं, बल्कि nixpkgs का
rustPlatformइस्तेमाल कर रहे हैं, जबकि Rust problem को बस हल्का-सा search करने पर भी वह मिल जाता।rust-overlayमेरे इस्तेमाल किए overlays में सबसे उपयोगी और powerful overlays में से एक है[0] https://github.com/oxalica/rust-overlay
nix2container[1] सच में dependencies को अलग layers में बांट सकता है। image के लिए जरूरी dependencies में से सिर्फ कुछ को रखने वाला layer explicit रूप से बनाया जा सकता है, और example भी इस section में है: https://github.com/nlewo/nix2container?tab=readme-ov-file#is...उदाहरण के लिए अगर images bash इस्तेमाल करती हैं, तो bash closure वाला layer explicit रूप से बनाया जा सकता है। यह layer सभी images में reuse होगा, और सिर्फ तब rebuild और repush होगा जब वह bash closure बदलेगा
single
/nix/storelayer की वजह से image बड़ी हो जाती है—यह defaultnixpkgs.dockerTools.buildImagefunction पर लागू होता है, लेकिन nix2container याnixpkgs.dockerTools.streamLayeredImageपर सही नहीं है। ये tools layers को Nix store में लिखने के बजाय existing store paths का इस्तेमाल करके image को सच में push करने वाली script बनाते हैं। nix2container implementation सभी layers के Nix store paths बताने वाली JSON file बनाता है, और Skopeo इस JSON को consume करके image को Docker daemon, registry, podman वगैरह में push करता हैसंदर्भ के लिए, मैं nix2container का author हूं
[1] https://github.com/nlewo/nix2container
यहां core problem language package managers द्वारा बढ़ावा दिए जाने वाले custom version soup वाले रवैये से चिपके रहना है। यह तरीका पूरी तरह unsustainable है
विकल्प Mise में packages के बीच version constraints समझने की क्षमता नहीं दिखती, और ऐसा भी नहीं लगता कि installed हर package आसपास के versions के साथ ठीक चलता है या नहीं, इसके लिए tests चलाता हो। तो आपको वही चीज बिल्कुल नहीं मिलती
कस्टम version soup टिकाऊ नहीं है, लेकिन लोग इसे इसलिए इस्तेमाल करते रहते हैं क्योंकि आम तौर पर यह ठीक काम करता है। इसके ठीक काम करने की एक वजह यह है कि operating system level libraries एक बहुत ज़्यादा conservative अलग दुनिया से आती हैं, और backward compatibility तोड़ने से जितना हो सके बचती हैं
इसलिए आप किसी stable और अच्छी तरह maintained operating system को आधार बना सकते हैं, उसके ऊपर mise या asdf जैसे tools से tools और language runtimes का कस्टम version soup रख सकते हैं, और फिर app चला सकते हैं। यह शायद ही कभी टूटता है। जब टूटता है, तो versions और छोटी-मोटी fixes से छेड़छाड़ करके उसे फिर चला लेते हैं और आगे बढ़ जाते हैं। इसके टूटने की बात annoying है, लेकिन अहम नहीं। friction बढ़ाना, learning मांगना, या ज़्यादा काम मांगना समय की बर्बादी है
इसके उलट कुछ लोग ऐसा समाधान ढूंढते हैं जिससे यह फिर कभी न टूटे। उनके लिए समस्या अहम है, इसलिए अगर समाधान friction, learning और extra work मांगे तो भी ठीक है। ऐसे लोग Nix चाहते हैं
ज़्यादातर लोग पहले group में आते हैं, इसलिए Railway जैसी grow करना चाहने वाली company आखिरकार उसी group के लिए सही solution चुनती है
Cargo.lockfile से Nix में Rust package build करना मामूली बात है। nixpkgs कस्टम version soup की उलटी दिशा में है, लेकिन Nix खुद उस तरीके को भी ठीक-ठाक handle कर सकता हैDevOps/SRE के तौर पर काम करने के अनुभव से, जब कोई dependencies वगैरह manage करने वाला system बनाने की कोशिश करता है, तो आम तौर पर दो रास्तों में से एक पर जाता है। Python को उदाहरण के तौर पर ले सकते हैं
विकल्प 1: “एक बड़ा shared monorepo इस्तेमाल करें।” फायदा यह है कि सब कुछ एक जगह होता है, जो चाहिए वह included होता है, और सब एक ही चीज़ इस्तेमाल करते हैं इसलिए vulnerabilities जैसी समस्याएं fix करना आसान होता है। नुकसान यह है कि कोई न कोई हमेशा कोई special version चाहता है, gradual rollout मुश्किल होता है इसलिए changes अक्सर big bang बन जाते हैं, और “छोटा Docker version कैसे बनाएं?” वाला सवाल आता है
विकल्प 2: “हर किसी का अपना conda/venv हो।” फायदा यह है कि हर किसी को ठीक वही मिलता है जो वह चाहता है, अनावश्यक packages नहीं इस्तेमाल होते, और staged upgrades आसान होते हैं। नुकसान यह है कि “आखिर conda environments कितने हैं?” वाली स्थिति बन जाती है, अलग-अलग groups की libraries शायद उसी Python library combination के साथ test न हुई हों, और अलग-अलग conda environments कहां हैं यह भी पता न होने से vulnerability management nightmare बन जाता है
इसलिए “यह नया तरीका सब कुछ solve कर देगा” जैसी बातों पर मैं हमेशा skeptical रहता हूं। career जितना लंबा होता जाता है, “solutions नहीं होते, सिर्फ trade-offs होते हैं” वाली बात उतनी ही सच लगने लगती है
Nix का थोड़ा ही experience होने के बावजूद, यहां के points ज़्यादा सही नहीं लगते
कहा गया है कि “Nix के version management से परिचित न होने वाले contributors के लिए यह clear या maintainable नहीं है”, “Node और Python में सिर्फ latest major versions support होने लगे”, लेकिन मुझे नहीं समझ आता कि यह unmaintainable क्यों है। अगर वजह यह है कि available versions की list बनानी पड़ती है, तो सवाल है कि क्या इसे automate नहीं किया जा सकता
उससे भी आगे, समझ नहीं आता कि Railway user के Nix इस्तेमाल करने के तरीके को define क्यों कर रहा है। Nix की core बातों में से एक यह नहीं है कि आप खाली machine को मनचाहे packages के exact versions से configure कर सकते हैं? Railway user और उस version के बीच में आकर restriction क्यों लगाए, यह समझ नहीं आता
अगर structure ऐसा है कि user सीधे Nix को देख ही नहीं पाता, तब भी असली सवाल बचता है। क्या package versions की list automate नहीं की जा सकती?
सच कहूं तो दिए गए reasons बहुत मजबूत नहीं लगते। शायद जिसने Nix introduce किया था वह चला गया, और बचे हुए लोगों को यह खास पसंद नहीं था। language खुद भी बहुत अच्छी नहीं है, और पुराना documentation भी शानदार नहीं था
फिर भी, उन्होंने जो stack चुना है उसे मैं पर्याप्त नहीं जानता, लेकिन curiosity है कि क्या वह Nix के करीब की determinism देता है। अगर नहीं, तो आगे चलकर यह परेशानी खड़ी कर सकता है या operations को और मुश्किल बना सकता है
/nix/storelayer वाली huge image तक ले जाता है, जिसमें build और runtime के लिए जरूरी सभी Nix-related packages और libraries होती हैं”यह कहना कुछ ऐसा है जैसे “car को आगे नहीं चला पाए, इसलिए car छोड़ रहे हैं।” यह उन चीज़ों में से एक है जो Nix सबसे reliably कर सकता है। result binaries में सच में referenced runtime dependencies को
/nix/storehash string matching से automatically detect करता हैअगर वे यह नहीं कर पाए, तो वे इसे काफी अजीब तरीके से इस्तेमाल कर रहे थे या कुछ गंभीर रूप से गलत किया था। पहले तो यह सोचना ही मुश्किल है कि Nix को इसे automatically solve करने से रोकने का तरीका क्या होगा
इसलिए मैं उनके Nix experience को बहुत deeply नहीं लूंगा। version management वाली बातें ऐसी बेहद common problems हैं जिनसे सब जूझते हैं, इसलिए अगर उन्होंने solution की कोशिश की होती तो वह ज़्यादा interesting होता
Nix arbitrary version guarantee नहीं, बल्कि commit guarantee देता है। edge cases आएंगे तो glibc changes या conflicting shared libraries की वजह से आपको परेशानी होगी
शायद थोड़ा देर हो गई है, लेकिन Nix-idiomatic तरीके से काम करवाने के लिए consulting देने में खुशी होगी। product अच्छा दिखता है
इतना ही नहीं, dependencies की dependencies, फिर उनकी dependencies, और यह सिलसिला चलता रहता है, इसलिए बड़े rebuilds अक्सर होते हैं
shared library conflicts तो बचेंगे, लेकिन यह solution बेहद wasteful है और development को भी painful बना सकता है। nixpkgs का staging process देखें तो पता चलेगा
फिर भी, लगता है कि यह दुनिया के 95% software से ज़्यादा “ठीक से काम करने की संभावना के साथ packaged” होगा
समझ नहीं आता कि nixpkgs hash पर depend करने के बजाय अपना derivation क्यों नहीं बना सके