1 puan yazan GN⁺ 2025-06-09 | 1 yorum | WhatsApp'ta paylaş
  • Railway, kullanıcı kodundan konteyner imajları oluşturan builder’ını yeniden tasarlayarak, 14 milyondan fazla uygulama derleyen Nixpacks deneyimini Railpack’e taşıdı
  • Nixpacks kullanıcıların %80’i için yeterliydi, ancak kalan 200 bin Railway kullanıcısı sürüm yönetimi, imaj boyutu ve önbellekleme sınırlarına takılabiliyordu
  • Railpack, Nix’in commit tabanlı sürüm yönetimi yerine major.minor.patch sürümleri, bağımlılık kilitleme ve Mise tabanlı kurulum akışıyla build tekrarlanabilirliğini artırıyor
  • BuildKit LLB ve Frontend’i doğrudan üreterek varsayılan Node imajı %38, varsayılan Python imajı %77 küçüldü; ortamlar arasında paylaşılabilen cache de mümkün hale geldi
  • Railpack şu anda Beta olarak servis ayarlarından etkinleştirilebiliyor; Railway, geniş dil desteğinden önce sık kullanılan dillerdeki olgunluğu artırmaya odaklanıyor

Railway’in yeni builder oluşturmasının arka planı

  • Railway, Railpack’i Railway builder’ının bir sonraki aşaması olarak duyurdu
  • Railpack, Nixpacks ile 14 milyondan fazla uygulama derlenirken edinilen deneyime dayanarak sıfırdan geliştirildi
  • Nixpacks yaklaşık 3 yıl önce yayımlandıktan sonra Railway’de kullanıcı kodundan imaj derlemenin varsayılan yolu haline geldi
  • Tüm kullanıcıların %80’i için iyi çalışıyordu, ancak kalan 200 bin Railway kullanıcısı sınırlamalar yaşayabiliyordu
  • Railway, kullanıcı tabanını 1 milyondan 100 milyona çıkarmak için builder’ı büyük ölçüde yükseltmesi gerektiğine karar verdi

Nixpacks’in Nix’te karşılaştığı sınırlar

  • En büyük sorun, Nix’in commit tabanlı paket sürüm yönetimiydi
    • Her paket yalnızca en yeni major sürümü sunuyordu
    • Sürüm, nixpkgs repo’daki belirli bir commit’e bağlıydı
  • Tüm patch sürümlerini destekleme girişimi, sürüm dizelerini commit SHA’leriyle doğrudan eşleyen bir yapıya dönüştü; bu da Nix sürüm yönetimine aşina olmayan katkıcılar için açık veya bakımı kolay değildi
  • Node ve Python gibi diller sonunda yalnızca en yeni major sürümü destekler hale geldi
  • En yeni paket sürümünü desteklemek için commit SHA güncellendiğinde başka paket sürümleri de birlikte değişebiliyordu
    • Varsayılan sürüm değiştiğinde, daha önce çalışan kullanıcı build’lerinin beklenmeyen hatalarla başarısız olma olasılığı artıyordu
    • Railway, kullanıcıların en yeni paketlere erişememesindense, başarılı olan build’lerin birden bozulmasını daha kötü görüyordu

İmaj boyutu ve önbellekleme sorunları

  • Nixpacks’in bağımlılıkları Nix ile getirme biçimi çoğu zaman büyük imaj boyutları oluşturuyordu
  • Build ve runtime için gereken Nix ile ilgili paketler ve kütüphaneler tek bir /nix/store katmanına giriyordu
  • Nix bağımlılıklarını ayrı katmanlara bölmenin yolu olmadığından nihai imaj boyutunu küçültmede sınırlar vardı
    • Railway bunu Nix’in kendisinin değil, Nixpacks’in Nix’i kullanma biçiminin bir sorunu olarak görüyor
  • Önbelleklemede de katman cache’inin ne zaman geçersiz kılınacağını kontrol etmek zordu
  • Railway her build’e bir dağıtım ID’si ortam değişkeni enjekte ediyor
    • Dockerfile’da bu değişken eklendikten sonra çalıştırılan katmanlar her zaman geçersiz hale geliyor ve cache’lenemiyordu
  • Nix’in temel unsurlarını kullanıcılardan gizleme yaklaşımı da pek uymuyordu
    • Kullanıcıların derivation’ın ne olduğunu anlamak ya da Node 22.14.0’ın neden unstable kanalındaki belirli bir archive sürümünde bulunduğunu bilmek zorunda olmamasını istiyordu

Railpack’in yapısal değişiklikleri

  • Railway, Nixpacks’te yaşadığı sorunları çözmek için Railpack’i geliştirdi
  • Nix’ten uzaklaşınca isim de Nixpacks’ten Railpack’e değişti
  • Kod tabanı, BuildKit kütüphanesi nedeniyle Rust’tan Go’ya taşındı
  • Railpack nihai imajın nasıl oluşturulduğunu daha doğrudan kontrol ediyor
    • BuildKit LLB ve Frontend’i doğrudan üretiyor
    • Nixpacks’e kıyasla varsayılan Node imajı %38, varsayılan Python imajı %77 daha küçük
    • Sürüm çözümleme ve çoğu paket kurulumu için Mise kullanıyor
    • Gelecekte başka yürütülebilir dosya kaynaklarını da destekleme payı bırakıyor
  • Başarılı bir build’de kullanılan bağımlılıklar kilitlenebiliyor
    • Varsayılan Node sürümü 22’den 24’e değişse bile build’in bozulmaması sağlanabiliyor
  • Gizli ortam değişkenlerinin build loglarında veya nihai imajda görünmemesi için BuildKit secrets kullanıyor

Railpack build’inin çalışma biçimi

  • Railpack süreci üç aşamaya ayrılıyor
    • Analyze: Koda bakarak kurulacak paketleri, çalıştırılacak komutları ve başlangıç komutunu belirler
    • Plan: Birden fazla aşamadan oluşan, JSON’a serileştirilebilir bir build planı oluşturur; her aşama başka aşamalardan veya tüm imajdan girdi alır
    • Generate: Planın girdi ve çıktılarına göre BuildKit build grafiğini kurar
  • Dockerfile doğrusal olsa da BuildKit grafiği çok daha paralel biçimde yapılandırılır
  • Her komut, multi-stage build’in kendi aşamasında çalıştırılır; böylece girdi katmanları ve nihai dosya sisteminin nasıl birleştirileceği ince ayrıntıda kontrol edilebilir
  • Railpack gerekli tüm build adımlarını içeren bir build planı üretir
    • Her aşama ihtiyaç duyduğu önceki aşamaları veya imajları açıkça tanımlar
    • Bu format, Nixpacks’te kullanılan yaklaşımdan daha düşük seviyelidir
    • Plan, LLB biçimindeki bir grafa dönüştürülüp yorumlanır
  • BuildKit sondan başlayıp geriye doğru çalışarak mümkün olduğunda cache’ten alır, yalnızca gerektiğinde komutları çalıştırarak istenen katmanları çözer
  • Belirli ortam değişkenleri değiştiğinde katmanı geçersiz kılmak için Railpack, kullanılan değişken değerlerini hash’ler ve bu hash’i içeren bir dosyayı girdi dosya sistemine mount eder
    • Kod ve kullanılan değişkenler değişmemişse katman cache’i hit alır
  • Railpack imajın nasıl oluşturulacağını tamamen tanımlayabilir

Railpack ile mümkün hale gelenler

  • Vite, Astro, CRA, Angular statik siteleri konfigürasyonsuz derleyip dağıtabilir
  • Build ile Railway UI arasındaki entegrasyon daha sıkı hale geldi
  • Railpack sürümü yayımlamadan da dillerin en yeni sürümleri desteklenebilir
  • Projenin birden fazla ortamında optimize katman önbelleklemesi kullanılabilir

Mevcut kullanım yöntemi ve destek kapsamı

  • Railpack şu anda Beta olarak sunuluyor ve servis ayarlarından etkinleştirilebiliyor
  • Halihazırda railway.com ve central station build’lerinde kullanılıyor
  • Şu anda desteklenenler şöyle
    • Node
    • Python
    • Go
    • PHP
    • Static HTML dağıtımı
    • Vite, Astro, CRA, Angular statik siteler için yerleşik destek
  • Railway, hem frontend hem backend’in kolayca dağıtılabildiği bir ortamı hedefliyor
  • Framework ve dil desteği eklenmeye devam ediyor
    • Talepler Help Station üzerinden alınabiliyor
    • Çekirdek API ve soyutlamalar kesinleşene kadar geniş destek yerine çok kullanılan dillerde derinliğe öncelik veriyor
  • Railpack açık kaynaklıdır ve dokümantasyon railpack.com adresinde sunuluyor

1 yorum

 
GN⁺ 2025-06-09
Hacker News yorumları
  • Nix hayranıyım ama Railway’in Nix’ten uzaklaşmasını eleştirmeye çalışmıyorum. Yalnız bazı şikâyetler daha fazla açıklama gerektiriyor gibi görünüyor.
    Nixpkgs harika ama Nix ile aynı şey değil; rastgele bir toolchain sürümünü almak istediğinizde Nixpkgs ideal olmayabilir, hepsi bu. Rust’ın rastgele sürümlerini getiren Nix araçları zaten gayet iyi ve diğer Nix tabanlı geliştirme araçları da bunun nasıl düzgün ele alınabileceğini göstermiş durumda.
    “Nix bağımlılıklarını ayrı katmanlara bölmenin yolu yok” sözü de bana anlaşılır gelmiyor. İstediğiniz şekilde bölebilirsiniz; Nixpkgs’in yerleşik Docker araçlarında da bunun için bir miktar destek var.
    Rust’tan Go’ya geçmeleri Nix ile doğrudan ilgili değil ama ilginç; ayrıca Railpacks ve Nixpacks sanki farklı kişiler tarafından yapılmış gibi de geliyor. Nix’e aşina olmayan kişilerin bir kurum içinde yarım kalmış bir Nix çözümünü devraldığında oldukça kötü şeyler yaşandığını gördüm; bu yüzden iş yerinde genelde böyle bir duruma yol açmamak için Nix kullanmıyorum.

    • Nix kullanmıyorum ama “Nixpkgs, Nix değildir” tepkisi biraz küçümseyici geliyor. Nixpkgs varsayılan ise ve alternatifler ek araştırma ve emek gerektiriyorsa, çoğu kullanıcı için fiilen Nix odur.
      “Katmanları istediğin şekilde bölersin” demek için de bunun açık, basit ve varsayılan davranış olup olmadığı önemli.
    • Nix’te temel kullanılabilirlik sorunları her gündeme geldiğinde “bunun etrafından dolaşmanın bir yolu var” yanıtının tekrarlanması yorucu. O geçici çözümler aktarılmış bilgi gerektiriyor; ana akım dillerden tamamen farklı çalışan bir dilde onlarca, hatta yüzlerce satır yazmanız gerekiyor; hata mesajları ve standart kütüphane belgeleri de iyi değil.
      İnsanların Nix’ten şikâyet etmesinin nedeni Turing-complete olmaması değil; ilgili ekosistemin idiomatik projeleriyle doğrudan uyum sağlayan basit bir birinci sınıf API sunmaması ve bu yüzden çözdüğü sorunlardan daha fazla sorun yaratması.
      Nix kullanmaya çalışan her proje sonunda Nix sorunlarını düzeltmek için kendi modüllerini yazmaya doğru sürükleniyorsa, belgeleri iyi olan ana akım araçlar yerine Nix kullanmak için güçlü bir neden kalmıyor. Bu örnek de tam olarak öyle görünüyor ve çoğu kişi muhtemelen sadece Docker’ı seçecektir.
      Geliştiricilere yönelik bir ürünün, pratik geliştirici deneyimi sorunlarını jeolojik zaman ölçekleri dışında bir hızda çözmek yerine ideolojik olarak saf flakes’e takılıp kalması sinir bozucu. Bunun gönüllü katkı olduğunu biliyorum ama kötü kullanıcı deneyimi yüzünden fiilen kullanımı zorlaşan bir şeye bu kadar çok teknik emeğin harcanması gerçekten çok üzücü.
    • Gözden kaçırılması kolay nokta şu: Railway’in kullanıcıları, rastgele paketler için kendi bağımlılıklarını ve sürümlerini belirtmek isteyen geliştiriciler.
      Nix’in Nixpkgs yapısıyla birlikte çalışma biçiminde, belirli bir paket sürümünü sabitlemek aslında tüm nixpkgs ağacının commit’ini sabitlemek anlamına geliyor. node/python/ruby paket derlemeleri paket dizininin dışındaki ağacın durumuna da bağlı olduğundan, sürüm ile commit arasında bir eşleme gerekiyor.
      Bu soyutlama sızdırdığı için Railway’in bunu kullanıcıya göstermesi gerekiyor; kullanıcı sadece yarn add new-fancy-nodejs-package-with-linked–native-deps yapmak istemişken kendini nixpkgs deposunun çeşitli durumlarını eşleştirmek zorunda kalmış halde bulabiliyor.
      Kapsamı dar kullanım alanlarında Nix’i Nixpkgs olmadan kullanmak sorun olmayabilir, ancak Railway gibi bir platformda bunu gerekçelendirmek zor görünüyor.
    • FreeBSD’yi denerken FreeBSD ports bağlamında da “Nix != Nixpkgs” tarzı sözler duymuştum. pkg genel olarak iyi çalışıyordu ama bir gün ports’tan vim’i özel USE bayraklarıyla derlemeye çalıştım; 20’den fazla bağımlılık çekti, her make menuconfigte seçenek sordu, sonra 23 paketten 16’ncısı “bu şuna ihtiyaç duyuyor, o da Fubar3.32.1 istiyor ama Fubar3, Fubar4 lehine deprecated oldu” gibi bir nedenle patlayınca vazgeçtim.
      Core OS geliştiricilerinin 10 binden fazla paketin hepsini destekleyemeyeceğini anlıyorum; ama özel özellikleri açıp kullanmaya çalıştığınızda başarısız olma olasılığının yüksek olduğu da açıkça belirtilmeli. Ya da ports’a girmeden önce bağımsız üretilmiş standart derlemenin başarılı olması gibi bir kriter konmalı; derlenmeyenler de ports listesinden çıkarılmalı.
    • Bence iyi özetlenmiş. Ek olarak, nixpkgs Nix’in kendisi olmasa da nixpkgs iyi olan taraflarından biri. NixOS kullanırken ilk kez Linux kernel’in en yeni sürümünü çıktığı gün kullanabiliyorum; bu oldukça harika. Yaşlandıkça Debian Stable’ı da kabullenmeye başladım ama onda hep birkaç yıl geriye dönmüşüm gibi hissediyorum.
      Nix dili saatlerce eleştirilebilir ama eski, zamanında ellerinden gelenin en iyisi yapılmış ve artık değiştirmenin değeri çok büyük olmayabilir. Nix derleme sistemi epey ilkel hissettiriyor ve yeniden derlenmesine gerek yokmuş gibi görünen şeyleri bile sık sık yeniden derliyor. Örneğin NixOS kurulum ISO’sunun derlemesinin önemli bir kısmı kernel’e geçirilen console=ttyS2,1500000n8 komut satırına bağlı; sadece seri port hızını değiştirseniz bile yaklaşık 3 dakikalık derleme gerekiyor. Komik ama bu yüzden Nix’i bırakacak değilim; sadece kendi derlemelerimde izin vermeyeceğim bir şey.
      Docker image’ları için Nix bana göre Nix’in en kötü olduğu alan. Uzun zaman önce Go yazılımı geliştirirken container image’ına Postgres’in pg_dump ikilisini eklemem gerekmişti; altyapı ekibinin önerisiyle Nix kullandık ve sıkıştırılmış Go ikilisi 50 MB olan image, nedeni belirsiz şekilde 1,5 GB’a çıktı. pg_dump 464 KB. Sonunda Bazel ve rules_debian ile apt paketini kurduk; distroless üzerinde çok daha temiz ve küçük oldu. Gerçek Nix deneyimime bakınca Nix sistemi hep 1,4 GB oluyor gibi geliyor. Kurulum ISO’su da 1,4 GB, yeni kurulmuş makine de 1,4 GB.
      Büyük bir C++ projesi derlemek istemek zaten iyi açılmış bir yol; C++’ı Rust ile değiştirmek de özü değiştirmiyor. Kütüphane durumunu daha az acılı hale getiren derleme sistemleri var; onlar da Nix kadar karmaşık ama bu kullanım için daha uygun olanları bulunuyor. Nix, başkalarının yazılımlarını ve nixpkgs’i derleyen bir derleme sistemi olmaya çalıştığı için çok genel bir noktaya yerleşiyor. Kendi yazılımınızı derlemek üzere tasarlanmış derleme sistemleri genelde o işi daha iyi yapıyor. Kişisel olarak Bazel’den memnunum ve Go’ya özel projelerde go build dışında pek başka bir şey kullanacağımı sanmıyorum; ama seçenek çok. Vakaların %99’unda Nix yerine bunları kullanıp, insanların home-manager ile güncel sürümü kurabilmesi için bir flake yazmak yeterli.
  • Sürüm seçimi kısmı tuhaf geliyor. nixpkgs’deki sürümler, bir sistemi çalıştırırken ya da derlerken anlamlı; ama bir platform olarak runtime ya da derleyici sağlıyorsanız, devenv gibi sürümü doğrudan sağlama yaklaşımına ihtiyaç var.
    Eski nodejs sağlamak için eski bir sistemi derlerseniz bağımlılıkların güvenlik yamalarını kaçırırsınız. Devenv bunu örneğin https://github.com/cachix/nixpkgs-python ile “tüm Python sürümlerini Nix ile her saat güncel tutma” şeklinde ele alıyor.
    Railway’in her build’e dağıtım ID’si ortam değişkeni enjekte etmesi, kurulumdan sonraki katmanda da yapılabilirdi. Paketleri birden çok katmana bölebilir, katman sayısını azaltmak için paketleme birimi otomasyonu da kullanabilirsiniz.

  • “Sorun Nix’in kendisinde değil, bizim onu kullanma biçimimizdeydi” ifadesi, doğru aracı doğru işte kullanın ilkesine iyi bir örnek. Nix bazı kullanımlar için harika, bazıları içinse berbat.
    Sorun şu ki Nix’in öğrenme eğrisi o kadar yüksek ki, onu değerlendirecek kadar anladığınızda zaten çok fazla zaman yatırmış oluyorsunuz; geri dönmek ziyan gibi geliyor ve asıl ihtiyacınızı çözmek için onu zorla uydurmaya başlıyorsunuz.

    • Ben de benzer hissediyorum; ama bir açıdan Nix, diğer işletim sistemlerine kıyasla daha genel bir programlama paradigmasına daha yakın. Biz işletim sistemlerini bu şekilde düşünmeye alışık değiliz sadece. Nix ifadelerinin girdileri var; paket deposu ve çok sayıda anahtar-değer çifti içeri giriyor, çıktı olarak bir Linux sistemi çıkıyor. Birkaç yıl sonra çok daha sıradan gelebilir.
      Bu paradigma sayesinde yapay zekanın spesifikasyona uygun shell.nix ya da configuration.nix oluşturması çok kolay. Örneğin Python paketleri, Linux paketleri, ortam değişkenleri, yol girdileri vb. içerebilir.
      Depoya, ilgili paketi eksiksiz destekleyen bir ortam eklemek için bunu sık kullanıyorum. flakes kullanmak daha yeniden üretilebilir olurdu; ancak flake.nix’i sürüm sabitlemesi olan bir shell.nix gibi anlıyorum ve hâlâ öğreniyorum.
  • Sürüm olmayan bir yere zorla sürüm sokmaya çalışıyorlar gibi görünüyor. Kare küpü yuvarlak deliğe sokmaya çalışmak gibi.
    “Varsayılan sürüm”ün ona bağımlı olanları bozması ne demek, anlamıyorum. Docker’da :latest etiketini kullanıp, her yeni sunucu ayağa kalktığında önceki “varsayılan” imajdan farklı bir sürüm geldiği için bozulmasına şaşırmak gibi.
    Bu blog yazısındaki açıklamaların hiçbirini anlamıyorum. Yazılımda “sürüm”ün ne olduğunu hiç bilmeyen insanlar gibi görünüyorlar.
    “Nix bağımlılıklarını ayrı katmanlara bölmenin yolu yok” iddiasının da neden böyle olduğunu anlamıyorum. Elbette /nix/store’u ihtiyaç duyduğunuz kadar çok katmana bölebilirsiniz. Konteynerleri ve Nix’i en başta nasıl kullandıklarını bilip bilmediklerinden bile şüpheliyim.
    Bu kadar bariz acemiliği görünce, önerdikleri çözümden çürük balık kokusu gelmesi de şaşırtıcı değil. Tipik NIH sendromu ve Nix ile çözemedikleri aynı sorunların yeni “çözüme” de aynen bulaşma ihtimali yüksek görünüyor.

    • Nix kullanmamayı, özellikle mantıklı olmadığı yerlerde, desteklerim. Ama birkaç saat ayırınca insanların bu sorunları zaten nasıl çözdüğünü görebilecekken, aslında sorun olmayan gerekçelerle çalışan bir sistemi sıfırdan yeniden yapmak temelde tuhaf görünüyor.
      Başkalarının da söylediği gibi nix2container ve flakes sahip oldukları tüm sorunları çözecek gibi.
      Sürüm yönetimi konusunda, 3 yıl önce yazdığım flakes hâlâ ilk yazdığım zamankiyle tamamen aynı sürümler ve aynı çıktıyla build ediliyor.
      Platform olarak piyasaya çıkıp yatırım toplamaya çalışıyorlarmış gibi geliyor.
      Düzenleme: Az önce nixpacks’in GitHub’ına baktım; Rust sorunu için üstünkörü bir aramayla bile bulunabilecek oxalica’nın rust-overlay’i[0] yerine nixpkgs’in rustPlatform’unu kullandıkları hemen göze çarptı. rust-overlay, kullandığım overlay’ler içinde en kullanışlı ve güçlü olanlardan biri.
      [0] https://github.com/oxalica/rust-overlay
    • Hedef VC yatırımı almaksa, Nix wrapper’ından çok dağıtım platformu daha iyi karşılık bulur.
  • nix2container[1] gerçekten bağımlılıkları ayrı katmanlara bölebiliyor. İmaj için gereken bağımlılıkların yalnızca bir kısmını içeren katmanları açıkça oluşturabilirsiniz; örnekler de şu bölümde var: https://github.com/nlewo/nix2container?tab=readme-ov-file#is...
    Örneğin imajlar bash kullanıyorsa, bash closure’ını içeren bir katmanı açıkça oluşturabilirsiniz. Bu katman tüm imajlarda yeniden kullanılır ve yalnızca ilgili bash closure’ı değiştiğinde yeniden build edilip yeniden push edilir.
    Tek bir /nix/store katmanı nedeniyle imajın büyümesi, varsayılan nixpkgs.dockerTools.buildImage fonksiyonu için geçerli; ancak nix2container veya nixpkgs.dockerTools.streamLayeredImage için doğru değil. Bu araçlar katmanları Nix store’a yazmak yerine, mevcut store path’lerini kullanarak imajı gerçekten push eden script’ler oluşturur. nix2container uygulaması tüm katmanların Nix store path’lerini tarif eden bir JSON dosyası oluşturur; Skopeo da bu JSON’u tüketerek imajı Docker daemon’a, registry’ye, podman’e vb. push eder.
    Bu arada nix2container’ın yazarı benim.
    [1] https://github.com/nlewo/nix2container

    • nix2container sayesinde bunu AWS ECR dağıtımında kullanıyorum ve build’ler arası tekrar süresi tek haneli saniyelere indi.
    • Docker imaj boyutu sorunu yaşadığım için nix2container’ı denemeye zaman ayırıyordum. Emeğin için teşekkürler.
  • Buradaki temel sorun, dil paket yöneticilerinin teşvik ettiği kişiye özel sürüm çorbası anlayışına tutunmak. Bu yaklaşım tamamen sürdürülemez.
    Alternatif olan Mise, paketler arası sürüm kısıtlarını anlama yeteneğine sahip görünmüyor; kurulan her paketin çevresindeki sürümlerle iyi çalışıp çalışmadığını test ediyor gibi de durmuyor. O zaman aynı şeyi elde etmiş olmuyorsunuz.

  • Özelleştirilmiş sürüm çorbası sürdürülebilir değil, ama insanların bunu kullanmaya devam etmesinin nedenlerinden biri çoğunlukla iyi çalışması. İyi çalışmasının nedenlerinden biri de işletim sistemi düzeyi kütüphanelerin çok daha muhafazakâr başka bir dünyadan gelmesi ve geriye dönük uyumluluğu bozmaktan mümkün olduğunca kaçınmaya çalışması
    Bu yüzden kararlı ve iyi yönetilen bir işletim sistemini temel alıp, onun üstüne mise veya asdf gibi araçlarla araçların ve dil runtime’larının özelleştirilmiş sürüm çorbasını yığarak uygulamayı çalıştırabilirsiniz. Neredeyse hiç bozulmaz. Bozulduğunda da sürümlerle ve küçük düzeltmelerle oynayıp tekrar çalışır hâle getirir, yolunuza devam edersiniz. Bozulmuş olması can sıkıcıdır ama önemli değildir. Sürtünmeyi artırmak, öğrenme gerektirmek veya daha fazla iş istemek zaman kaybıdır
    Buna karşılık bir daha asla bozulmamasını sağlayacak çözümü arayanlar da var. Bu kişiler için sorun önemli olduğundan, çözümün sürtünme, öğrenme ve ek iş gerektirmesi kabul edilebilir. Nix’i isteyenler bu kişiler
    Çoğunluk ilk grupta yer aldığından, büyümek isteyen Railway gibi bir şirket sonunda o gruba uygun çözümü seçer

    • “Özelleştirilmiş sürüm çorbası” tutumunun ne anlama geldiğini ve alternatifin ne olduğunu biraz daha açıklayabilir misiniz?
    • Doğru yapılırsa ikisine de sahip olabilirsiniz. Örneğin Cargo.lock dosyasından Nix ile Rust paketleri derlemek önemsiz bir iş. nixpkgs, özelleştirilmiş sürüm çorbasının ters yönünde, ama Nix’in kendisi bu yaklaşımı da gayet iyi idare edebilir
  • DevOps/SRE olarak çalışmış biri olarak, biri bağımlılıkları vb. yönetecek bir sistem kurmaya çalıştığında genellikle iki yoldan birine gidiyor. Python örnek alınabilir
    Seçenek 1: “Tek büyük paylaşımlı repo kullanalım.” Avantajı, her şeyin tek yerde olması, gerekenlerin içinde bulunması ve herkes aynı şeyi kullandığı için güvenlik açığı gibi sorunları düzeltmenin kolay olması. Dezavantajı, birilerinin her zaman özel bir sürüm istemesi, kademeli dağıtımın zor olup değişikliklerin kolayca big bang’e dönüşmesi ve “küçük Docker sürümünü nasıl yapacağız?” sorusunun ortaya çıkması
    Seçenek 2: “Herkesin kendi conda/venv’i olsun.” Avantajı, herkesin tam olarak istediğini alması, gereksiz paketleri kullanmaması ve aşamalı yükseltmenin kolay olması. Dezavantajı, “kaç tane conda ortamı var böyle?” noktasına gelinmesi, farklı grupların kütüphanelerinin aynı Python kütüphanesi kombinasyonuyla test edilmemiş olabilmesi ve farklı conda ortamlarının nerede olduğunu bile bilmediğiniz için güvenlik açığı yönetiminin kâbusa dönüşmesi
    Bu yüzden “bu yeni yöntem her şeyi çözüyor” sözlerine her zaman şüpheyle yaklaşıyorum. Deneyim arttıkça “çözüm yok, yalnızca trade-off var” sözü giderek daha doğru geliyor

  • Nix deneyimi az olan biri olarak baksam bile buradaki argümanlar pek doğru görünmüyor
    “Nix’in sürüm yönetimine aşina olmayan katkıcılar için açık veya bakımı yapılabilir değil”, “Node ve Python yalnızca en yeni majör sürümleri destekler hâle geldi” deniyor; bunun neden bakımı yapılamaz olduğunu anlamıyorum. Kullanılabilir sürümlerin listesini oluşturmak gerektiği içinse, bunun otomatikleştirilemeyeceğini merak ediyorum
    Daha da ötesi, Railway’in kullanıcının Nix’i kullanma biçimini neden tanımladığını anlamıyorum. Nix’in temel noktalarından biri, boş bir makineyi istenen paketlerin tam sürümleriyle yapılandırabilmek değil mi? Railway’in kullanıcı ile o sürüm arasına girip neden kısıtlama getirmesi gerektiğini anlamıyorum
    Eğer yapı kullanıcının Nix’i doğrudan görmesini engelliyorsa, asıl soru hâlâ ortada. Paket sürüm listesi otomatikleştirilemiyor mu?

    • Sürüm kısıtlaması, Nix cache’inin eski sürümleri tutmamasından kaynaklanıyor. Bu yüzden eski sürümleri kullanırsanız kaynaktan derlemek gerekiyor. Eski sürümler için cache’i kendileri sağlamak istememişler gibi geliyor; ama bunun o kadar büyük bir çaba gerektireceğini sanmıyorum
      Açıkçası sunulan nedenler pek sağlam görünmüyor. Belki Nix’i getiren kişi ayrıldı ve kalanlar onu pek sevmiyordu. Dilin kendisi çok iyi değil, eski belgeler de harika değildi
      Yine de seçtikleri stack’i yeterince bilmiyorum; Nix’e yakın düzeyde determinizm sağlayıp sağlamadığını merak ediyorum. Sağlamıyorsa ileride ayaklarına dolanabilir veya operasyonları daha zor hâle getirebilir
    • Yazıda “Nixpacks’in bağımlılıkları çekme biçimi, tek bir /nix/store katmanından oluşan devasa bir imaja yol açıyor; build ve runtime için gereken tüm Nix ile ilgili paketler ve kütüphaneler burada bulunuyor” deniyor
      Bu, “arabayı ileri götüremediğimiz için arabadan vazgeçiyoruz” demeye benziyor. Bu, Nix’in en güvenilir şekilde yapabildiği işlerden biri. Sonuç binary’de gerçekten referans verilen runtime bağımlılıklarını /nix/store hash dizesi eşleştirmesiyle otomatik algılar
      Bunu yapamıyorlarsa oldukça garip kullanıyorlar ya da ciddi şekilde yanlış bir şey yapmışlar demektir. Nix’in bunu otomatik çözmesini engellemenin bir yolunu düşünmek bile zor
      Bu yüzden onların Nix deneyimini çok ciddiye almazdım. Sürüm yönetimiyle ilgili kısım herkesin yaşadığı çok genel bir sorun; çözmeye çalışmış olsalardı daha ilginç olurdu
    • Kullanıcının Nix’i doğrudan görmesini engelleyen bir yapı olduğu anlayışı en azından benim anlayışımla aynı
    • Projede hiç Dockerfile olmasa bile kodu Railway’e push edince imajı Nixpacks ile derliyor. Build loglarında Nix ile ilgili şeyler görünür, ama çoğu arka planda çalışır
  • Nix keyfî sürüm garantisi değil, commit garantisi sağlar. Sınır durumlar çıktığında glibc değişiklikleri veya çakışan paylaşımlı kütüphaneler yüzünden uğraşmanız gerekecek
    Biraz geç kalmış gibi ama Nix’e özgü yöntemlerle çalışır hâle getirmek için danışmanlık vermekten memnuniyet duyarım. Ürün güzel görünüyor

    • Nix, paylaşımlı kütüphane uyumsuzluğu sorununu aşırı muhafazakâr biçimde çözer. Herhangi bir şey değiştiğinde, anlamlı bir değişiklik olsun ya da olmasın; yalnızca yorum düzeltmesi, belge değişikliği veya test case eklemesiyle bile tüm bağımlı öğeleri yeniden derler
      Üstelik yalnızca bunlar değil, bağımlı öğelerin bağımlıları, onların bağımlıları diye devam eder ve sık sık büyük ölçekli yeniden derlemeler ortaya çıkar
      Paylaşımlı kütüphane çakışmalarından kaçınırsınız, ama bu çözüm son derece israflıdır ve geliştirmeyi de acılı hâle getirebilir. nixpkgs’in staging sürecine bakınca anlaşılır
    • Nix’in değer önermesini tamamen anlıyorum. Ama “uğraşmanız gerekecek” ifadesinin biraz abartılı olduğunu düşünüyorum. En fazla “Nix’e kıyasla oldukça önemli garantileri kaybediyorsunuz” denebilir
      Yine de dünya yazılımlarının %95’inden daha “doğru çalışma ihtimali yüksek şekilde paketlenmiş” durumda olacaktır
  • Neden nixpkgs hash’ine bağlı kalmak yerine kendi derivation’larını oluşturamadıklarını anlamıyorum