- Jika image Docker sudah digunakan sebagai unit deployment, Nix menjadi titik masuk untuk mencoba build deterministik dan penguncian dependensi tanpa banyak mengubah workflow
docker build pada umumnya mudah bergantung pada kondisi internet publik, seperti repositori Ubuntu atau unduhan eksternal, sehingga sulit mereproduksi image yang sama setelah waktu berlalu
- Nix mengetahui dependensi yang diperlukan pada level paket, sehingga dengan
dockerTools.buildLayeredImage dimungkinkan membuat konfigurasi yang hanya mengunggah ulang layer yang berubah
- Contoh
douglas-adams-quotes berbasis Go menunjukkan bahwa binary bisa dibuat dengan pkgs.buildGoModule, lalu dimuat dan dideploy seperti image Docker biasa melalui nix build.#docker dan docker load <./result
- Jika beberapa service dalam monorepo berbagi layer dan cache Nix, waktu serta biaya build dapat dikurangi saat mereproduksi image dari commit lama dan melakukan deployment berulang
Mengapa memasang Nix ke proses build image Docker
- Nix memiliki tiga karakter sekaligus: package manager, bahasa, dan sistem operasi
- Instruksi build paket ditulis dengan bahasa Nix
- Package manager Nix dapat membuat software, tool, image NixOS, image container, dan lainnya berdasarkan instruksi tersebut
- Mengadopsi Nix ke pipeline CI/CD yang sudah ada tidak mudah
- Nix berbeda dari cara kerja yang familier bagi banyak developer
- Kecuali berada di lingkungan yang bisa memulai semuanya dari awal, seperti startup baru atau homelab, hambatan adopsinya besar
- Organisasi yang sudah menggunakan Docker dapat mulai menerapkan Nix dari build image container untuk bereksperimen tanpa banyak merusak alur deployment yang ada
Titik rapuh dalam build Docker
- Docker dan containerization telah diadopsi secara luas, sehingga image Docker digunakan seperti format paket universal de facto di internet
- Platform seperti Fly.io, Railway, dan Render menggunakan image Docker, bukan image VM sembarang atau program Linux berbentuk tarball
- Build Docker tidak selalu deterministik
- Dockerfile yang umum terlihat di internet kebanyakan berhasil dibuild, tetapi persentase kecil kegagalan dapat berujung pada masalah operasional
- Salah satu kelemahan terbesar adalah build Docker mengakses internet publik
- Ini diperlukan untuk mengunduh paket dari repositori Ubuntu
- Saat perlu membuat ulang image yang sama di kemudian hari, sulit mengembalikan kondisi persis repositori Ubuntu pada saat itu
- Ubuntu 18.04 akan mencapai akhir masa dukungan pada tahun terkait, sehingga sesuatu yang bergantung pada versi itu mungkin baru diketahui setelah terjadi gangguan
- Menambahkan paket ke image Docker dengan cara sederhana dapat menciptakan ruang terbuang
- Jika
apt-get upgrade dijalankan di awal build, file di dalam image container dapat diganti
- File sebelum diganti dapat tetap berada di layer dan menumpuk seperti salinan bayangan
Cara Nix menangani layer Docker
- Nix mengetahui dependensi yang diperlukan sebelumnya, dan dapat membaginya ke dalam layer Docker sesedikit mungkin
- Mengubah satu baris kode tidak membuat
apt atau npm perlu memasang ulang dependensi
- Hanya bagian minimum yang benar-benar berubah yang dapat direfleksikan dalam pembaruan image
dockerTools adalah kumpulan tool untuk memasukkan paket Nix dan dependensinya ke dalam image Docker
- Image Docker yang dibuat dengan Nix secara garis besar terbagi menjadi dua pendekatan
- Image tanpa layer: program, dependensi, dan item tambahan seperti sertifikat root TLS dimasukkan ke satu folder dan diekspos sebagai image satu layer
- Image berlayer: tiap dependensi ditempatkan sebagai layer image terpisah, sehingga hanya bagian yang benar-benar berubah yang perlu diunggah
- Docker sendiri juga memiliki penyimpanan berbasis konten, tetapi sulit memanfaatkannya secara penuh hanya dengan
docker build
- Image berlayer dari Nix menggunakan layer per paket, sehingga dependensi seperti
glibc cukup diunggah sekali
- Namun, jika library tersebut perlu dimodifikasi, layer itu harus diunggah ulang
Contoh service Go: Douglas Adams Quotes
- Service contoh adalah program Go yang menyediakan kutipan Douglas Adams
- Proyek Go module mendefinisikan paket Nix dengan
pkgs.buildGoModule
bin = pkgs.buildGoModule {
pname = "douglas-adams-quotes";
inherit version;
src = ./.;
vendorHash = null;
};
- Definisi ini menggunakan template Go module untuk mengatur compiler Go, compiler C untuk CGo, dan unduhan dependensi eksternal
pname adalah nama paket
version dibuat otomatis dari commit Git service
src = ./.; menggunakan kode sumber dari direktori kerja saat ini
- Jika tidak ada dependensi selain standard library,
vendorHash = null dapat digunakan
- Jika ada dependensi eksternal, hash semua dependensi harus ditentukan atau
gomod2nix dapat digunakan
- Paket dibuild dengan perintah berikut
nix build .#bin
- Image berlayer Docker dapat dibuat dengan
dockerTools.buildLayeredImage
docker = pkgs.dockerTools.buildLayeredImage {
name = "registry.fly.io/douglas-adams-quotes";
tag = "latest";
config.Cmd = "${bin}/bin/douglas-adams-quotes";
};
- Jika binary server yang sudah dibuild ditentukan pada
config.Cmd, item yang diperlukan ikut disalin
glibc dan item yang dibutuhkan untuk menjalankannya juga disertakan
- Paket tambahan seperti sertifikat root CA dapat dimasukkan ke
contents
docker = pkgs.dockerTools.buildLayeredImage {
name = "registry.fly.io/douglas-adams-quotes";
tag = "latest";
contents = with pkgs; [ cacert ];
config.Cmd = "${bin}/bin/douglas-adams-quotes";
};
- Image dibuat dan dimuat ke daemon Docker dengan perintah berikut
nix build .#docker
docker load < ./result
- Jika dibuka dengan
dive, tiap layer terlihat menambahkan paket berbeda dari nixpkgs, lalu pada akhirnya item-item tersebut di-symlink ke root image
Efek berbagi layer dalam monorepo
- Jika ada beberapa service dalam repositori yang sama, image Docker yang dibuat dengan Nix dapat berbagi layer
- Dibagikan tanpa konfigurasi terpisah
- Jika ingin melakukan ini hanya dengan Docker, biasanya perlu membuat beberapa base image bersama, yang dapat berisi tool dan konten tidak perlu yang tidak digunakan sebagian service
- Sebagai contoh, repositori
Xe/x adalah monorepo berisi 10 tahun side project, eksperimen, dan tool
- Berbagai proyek dideploy ke sekitar tiga platform
- Pekerjaan untuk memasukkannya ke image Docker telah dilakukan agar mengerucut ke basis deployment bersama
- Saat pembaruan satu service di-push, sebagian pembaruan yang dibagikan dengan kebanyakan service lain juga ikut di-push
- Pendekatan ini menghemat waktu dan biaya di berbagai proyek
Bagian yang sulit dikejar hanya dengan cache Docker
- Dengan caching Docker, secara teori image juga bisa dibuild seefisien Nix
- Namun untuk menghasilkan efek yang sama dengan pendekatan Docker, tahap build dapat menjadi sulit dipelihara
- Shared library harus dipasang ke layer terpisah
- Network stack harus dinyalakan kembali selama build, sehingga reproduksibilitas melemah
- Search path, flag compiler, dan pengaturan terkait CGo harus disesuaikan lagi
dockerTools.buildLayeredImage dari Nix menangani detail memasukkan paket ke container, sehingga konfigurasi menjadi lebih sederhana
Reproduksi titik waktu lampau dan cache Nix
- Salah satu keunggulan besar Nix adalah kemampuannya membangun ulang secara persis software dari titik waktu lampau
- Saat perlu mereproduksi bug pada lingkungan pelanggan tertentu di kemudian hari, image Docker yang sama dapat dibuat ulang
- Build paket berperan mengunci seluruh kondisi software dan dependensi pada satu titik waktu
XeDN adalah proyek yang telah dikerjakan selama beberapa tahun, dan versi 14 bulan lalu dapat dibuild dengan perintah berikut
nix build github:Xe/x/567fdc2#xedn-docker
- Perintah ini membuild target
xedn-docker dari commit tertentu di GitHub repo Xe/x
- Jika dimuat ke daemon Docker, image dengan byte yang sama seperti saat itu akan dibuat
- Contoh ini juga menyertakan Go 1.19
- Untuk melakukan reproduksi yang sama hanya dengan build Docker biasa, mungkin diperlukan biaya penyimpanan yang besar
- Cache Nix menyimpan output dari perintah Nix agar tidak perlu dibuild ulang nanti
- Paket seperti
nokogiri tidak perlu dibuild ulang di tiap laptop developer
- Hasil yang sudah dibuild di cloud dapat diambil
- Garnix digunakan untuk CI semua proyek flakes, dan melaporkan status build pada tiap commit
- Konfigurasi mesin homelab juga dibuild dengan Garnix, sehingga saat memperbaruinya setiap malam, konfigurasi terbaru diambil dari cache Garnix alih-alih dibuild sendiri
Kesimpulan sebagai artefak deployment
- Nix bisa dipandang sebagai builder image Docker yang lebih baik daripada builder image Docker milik Docker
- Nix membuat kita menentukan hasil, bukan menuliskan langsung detail langkah-langkah untuk mencapai hasil itu
- Di lingkungan yang sudah menggunakan Docker, menerapkan Nix mulai dari build image Docker menjadi jalur adopsi yang realistis
- Image Docker yang dibuat dengan Nix dapat berbagi layer antarbagian dalam monorepo
- Berkat cache binary, kode yang sudah pernah dibuild di masa lalu tidak perlu dibuild ulang
- Artefak akhirnya adalah image container biasa yang dapat dideploy ke platform seperti AWS, Google Cloud, dan Fly.io
1 komentar
Opini Hacker News
Saya sudah beberapa kali mencoba menyukai Nix, tetapi sekarang rasanya saya harus menyerah
Ada 2 sistem yang menjalankan Nix, dan saya takut menyentuhnya; dulu keduanya pernah rusak sampai harus saya instal ulang dari nol. Secara teori Nix itu idempoten dan deterministik, tetapi dalam praktiknya kita harus memahami deterministik terhadap apa, dan kalau tidak benar-benar memahami perilaku semua bagian yang menjadi dependensi, kita akan berhadapan dengan hasil aneh, error yang ganjil dan tidak membantu, atau bahkan tidak ada umpan balik sama sekali
Dokumentasinya, meski lengkap dan secara teknis benar, sangat sulit dipahami, dan tutorialnya hanya mengantar sampai 80% jalan. Begitu keluar dari jalur itu, kita harus merakit sendiri, dan itu menuntut pengetahuan dari pengalaman bertahun-tahun serta banyak frustrasi, yang sudah tidak ingin saya tanggung lagi. Keunggulan Docker justru ada pada kekacauannya: cukup tahu kira-kira soal shell dan package manager distro, hampir apa pun bisa dibuat; kalau ada masalah, berkat tool yang sudah berumur puluhan tahun, diagnosis dan perbaikannya jauh lebih mudah
Nix itu seperti Emacs: dengan kesabaran serta pengetahuan yang dalam dan visioner, kita bisa melakukan apa saja, tetapi tampaknya pilihannya hanya benar-benar tenggelam di dalamnya atau menjaga jarak sambil mengamati
Kalau build dua kali berturut-turut di mesin yang sama, hasilnya sama, tetapi seiring waktu ketika package manager dan tag base image diperbarui, hasil rebuild sebulan kemudian bisa sepenuhnya berbeda. Kalau tim mengelola sekitar 40 container, memperbaiki container menjadi bagian besar dari pekerjaan
Karena itu, secara teori Nix seharusnya sempurna, tetapi ia terlalu berbeda sehingga tool vendor tidak berjalan di Nix, dan saat terjadi error pun sulit menemukan solusi cepat di web. Karena frustrasi itu, saya membuat https://www.stablebuild.com, yang menyediakan build deterministik berbasis Docker di atas container Ubuntu, Debian, dan Alpine. Ini terdiri dari cache pull-through Docker Hub yang immutable, salinan harian lengkap repository paket Ubuntu/Debian/Alpine, salinan harian PPA populer dan indeks PyPI, serta cache immutable untuk file/URL arbitrer
Dalam praktiknya mudah digunakan dan mudah di-debug, dengan kompatibilitas software yang luas, sehingga pada container yang dipindahkan ke StableBuild, jumlah masalah akibat nondeterminisme adalah 0
Saya pernah menghabiskan waktu untuk memahami mengapa
nix developtidak berperilaku seperti dokumentasinya, dan bagaimana membuatnya berperilaku demikian. Dokumentasi mengatakan bahwa secara default kita masuk ke environment waktu build, tetapi default sebenarnya tidak tersegel, dan nama opsi command line juga membingungkan, sehingga saya harus menggali pengetahuan dari sourceSaya juga berharap edge case yang merusak reproduksibilitas dibahas lebih eksplisit. Kode floating-point sensitif terhadap urutan operasi, dan state juga bisa bocor karena preemption sistem operasi; kalau hal-hal yang obvious pun tidak dinyatakan, orang akan menembak kakinya sendiri
Jika memakai konfigurasi “Erase your darlings”, sebagian besar state yang tidak dapat direproduksi di luar akun pengguna bisa dihilangkan. Memang agak merepotkan, tetapi rasanya apa sih yang tidak merepotkan di NixOS
https://grahamc.com/blog/erase-your-darlings/
Saya tidak memedulikan bagian dalam akun pengguna, dan saya tidak menyukai Home Manager
Docker baik-baik saja, tetapi di Mac performanya kurang bagus; Nix menyenangkan karena membuat instalasi dan perilaku yang sama di banyak mesin menjadi hal sepele. Dokumentasi Nix buruk, tetapi ChatGPT-4 sangat bagus untuk menyelesaikan masalah Nix
Rasanya 90% masalah Nix muncul karena saya mencoba melakukan sesuatu yang bukan “cara Nix”
Saya sudah mencoba hampir semua package manager distro, dan tanpa melakukan hal khusus pun entah bagaimana semuanya pernah saya rusakkan. Fedora Kinoite tetap tangguh meski menambah/menghapus layer, update harian, bahkan rebase dari Silverblue. Secara pribadi, saya rasa rpm-ostree akan menggantikan Nix
Saya melihat Nix dan NixOS berada dalam kondisi yang mirip dengan git sebelum GitHub
Ide dasarnya berlandaskan ilmu komputer yang lebih serius dibandingkan pendekatan lama seperti SVN atau Docker, dan meski plumbing internalnya masih bermasalah, itu tidak lebih buruk; namun tool dan dokumentasi yang user-facing belum berada di level adopsi arus utama
Peluncuran flox mungkin sudah mengubah hal ini: https://flox.dev. Hampir mulus, dan itu tidak mengherankan karena berasal dari orang-orang eks DE Shaw
Nix tidak terlalu berarti tanpa flakes dan
nix-command, tetapi keduanya didokumentasikan sebagai eksperimental dan secara default juga nonaktif. Dokumentasinya membaik, tetapi masih kurang; nixlang keren jika dipelajari dengan baik, tetapi tidak bisa diterima sebagai hambatan masuk ke arus utama.nix-env -iA foopada praktiknya sering kali bukan perilaku yang diinginkan, jadi Nix lebih mirip senjata rahasia bagi perusahaan yang mampu menanggung keahlian internal daripada package manager seperti yang diiklankanflox menurunkan hambatan untuk “coba sekali dan langsung mendapat pengalaman yang lebih baik”. Nix/NixOS atau sesuatu yang serupa pada akhirnya akan mendorong Docker ke belakang seperti Subversion, tetapi itu tidak akan terjadi sampai ada momen seperti GitHub, lalu akan terjadi sekaligus
Sebagian besar keluhan tentang Nix di thread ini secara teknis keliru, tetapi sangat bisa dipahami, dan yang lebih penting, bukan salah pengguna. Saya tahu generasi yang mengenal dunia tanpa git/GitHub makin berkurang, tetapi ada baiknya mendengar Linus menjelaskan di depan orang-orang yang lolos standar rekrutmen awal Google mengapa mereka perlu peduli pada tool yang terasa rumit
https://youtu.be/MjIPv8a0hU8?si=QC0UnHXRdMpp2tI4
Kami sudah cukup lama membangunnya, dan kami ingin mendengar jika ada hal yang layak diprioritaskan agar bisa membuatnya lebih baik
git seperti itu, tetapi Nix belum, jadi saya tidak begitu yakin apakah momen seperti GitHub akan membantu
Tulisan blog ini melewatkan penjelasan mengapa layer Docker bersama berguna
Alasannya adalah caching: makin banyak image yang berbagi layer yang sama, makin banyak hal yang bisa di-cache, sehingga startup container menjadi lebih cepat
Alasan Docker lemah dalam hal ini adalah, untuk mendapat manfaat caching, saat membangun image layer yang dihasilkan harus semirip mungkin dengan layer yang sudah ada. Misalnya, jika hari ini menjalankan
apt-get install python3dan tidak ada update baru, seharusnya layer yang dihasilkan persis sama seperti kemarin; tetapi layer Docker di-cache berdasarkan hash file, jadi semua file harus persis sama, termasuk metadata seperti waktu pembuatanNix sudah menyimpan dependency sebagai hash, jadi jika versinya sama dan konfigurasinya sama, layer-nya akan selalu sama
Dependency biasanya membentuk graf, bukan tree, sehingga ini cepat merepotkan. Tool alternatif seperti Nix atau mungkin Bazel tidak punya batasan ini, dan dapat memetakan graf dependency ke layer Docker untuk mencapai caching yang granular. Itu cara yang tidak bisa diekspresikan dengan Dockerfile
apt-gettidak otomatis diinvalidasiItu hanya berubah saat memakai
--no-cacheatau ada perubahan pada layer di atasnyaSelama 2–3 hari terakhir saya bergulat untuk membangun image Docker di Darwin, dan tulisan ini terasa seperti semesta sedang mengolok-olok saya
Nix jelas merupakan alat terbaik untuk tujuan yang diinginkan, tetapi ada sudut-sudut gelap dan terbengkalai yang seperti menyedot jiwa. Saya menyukainya, tetapi kadang rasanya seperti Morty yang terseret ke petualangan compiler-land milik Rick
Docker pada dasarnya lebih mirip penjara yang berisi binary Linux. Di Linux, Anda cukup membangun binary, memasukkannya ke container, selesai; kode Nix-nya juga sederhana. Jika Anda bisa membangun kodenya, membuat container hanyalah satu langkah tambahan
Namun Docker membutuhkan binary Linux, dan di Mac, Docker Desktop menjalankan VM Linux, melakukan semua pekerjaan di dalamnya, lalu menyembunyikan fakta itu. Nix tidak melakukan hal seperti itu, jadi pilihannya ada dua
Pertama, melakukan cross-compilation, tetapi glibc pun harus bisa di-cross-compile, dan meski sebagian besar dependency komunitas mungkin bisa, beberapa paket bisa saja tidak diperhatikan oleh penulisnya untuk cross-compilation. Selain itu, Hydra yang mengisi cache Nix standar tidak melakukan build cross-compilation, sehingga Anda bisa saja membangun lama lalu gagal
Kedua, memasang builder Linux ke Mac dan mengirim pekerjaan build
x86_64-linuxke sana. Bisa berupa mesin fisik, VM, bahkan container Docker NixOSOpsi pertama tampak seperti cara yang benar, tetapi opsi kedua lebih praktis. Masalah yang Anda alami kemungkinan besar karena mencoba opsi pertama, dan ini menuntut banyak pengalaman bukan hanya dengan Nix, tetapi juga cross-compilation. Akan bagus jika Hydra juga membangun cross-compilation dari Darwin ke Linux sehingga menyediakan cache dan mencegah kerusakan, tetapi biayanya juga akan meningkat. Sepertinya lebih baik mencoba solusi kedua
Sepertinya pernah ada solusi resmi: https://ryantm.github.io/nixpkgs/builders/special/darwin-bui...
Pada beberapa stack, cross-compilation tidak terlalu tangguh, jadi kami melakukan cross-compilation
{aarch64,amd64} x {linux,darwin}dengan Docker. Kami menjalankan beberapa Docker di atas Darwin aarch64 untuk mengompilasi semuanya, dan pengalamannya bagushttps://github.com/gytis-ivaskevicius/high-quality-nix-conte...
Ada satu-dua bug, tetapi tampaknya terutama terkait volume, dan build image Docker ditangani dengan cukup baik. Bagian yang lebih kasar adalah kecepatannya, karena kombinasi hardware dan fakta bahwa Docker harus mengemulasi VM Linux membuatnya terasa cukup terpukul
Pengalaman membangun image Docker untuk aplikasi Java dengan Nix tidak terlalu bagus
Setelah
gradle2nixdihentikan, tampaknya tidak ada alternatif yang jelas untuk aplikasi Java berbasis Gradle. Dulu saya pernah mengajak seorang teman untuk mencoba membuat image Docker sekecil mungkin untuk aplikasi Spring Boot sederhana, tetapi hasil yang dibuat dengan Nix berukuran dua kali lebih besar daripada image yang dibuat tanpa NixKodenya bisa dilihat di sini: https://github.com/jossephus/Docker_challenge/blob/main/flak...
Zulu dan JDK yang disertakan Gradle sebagai argumen
jdksama-sama masuk. Jika melihatgradleGendi nixpkgs, maksudnya akan terlihat. Maaf soalgradle2nix; sedang ada upaya perbaikan yang tidak terlalu terasa seperti hackKira-kira seperti ini: https://gist.github.com/takeda/17b6b645ad4758d5aaf472b84447b...
Semuanya ditautkan dengan musl, saat mengompilasi Python saya menonaktifkan semua paket yang tidak dipakai aplikasi, dan menghapus bagian boto3/botocore yang tidak digunakan. boto3/botocore saja sudah lebih dari 100MB
Paket Nix pada dasarnya menargetkan sistem operasi NixOS, jadi dalam situasi umum dengan ruang disk yang cukup, biasanya diinginkan semua fitur aktif. Akibatnya banyak dependensi yang tidak diperlukan ikut terbawa. Sebaliknya, image Alpine dirancang untuk Docker, dengan tujuan mematikan fitur tambahan pada paket, sehingga hasilnya lebih kecil
Untuk membuat image kecil, hal-hal yang tidak diperlukan harus dimatikan dengan
override. Misalnya zulu menyertakan hal-hal seperti alsa, fontconfig, freetype, xorg, cups, gtk, cairo, dan ffmpeg. Teman saya dengan hati-hati hanya mengekstrak file yang diperlukan lalu memasukkannya ke container, sedangkan di sisi Nix, seluruh paket zulu beserta semua dependensinya dibundelPertama, perbaiki agar hanya satu JDK yang disertakan, lalu ukuran JDK bisa diperkecil lagi dengan metode di atas. Menggunakan
openjdk_headlessmungkin akan lebih sederhanahttps://github.com/NixOS/nixpkgs/blob/master/pkgs/developmen...
https://github.com/GoogleContainerTools/jib/tree/master/jib-...
openjdk_headlessmelewati dependensi GTK dan X yang tidak diperlukan SpringAlih-alih Zulu, saya mengubahnya agar berbasis build OpenJDK headless dari Nixpkgs untuk menghapus dependensi library GUI, lalu membuat JRE minimal khusus dengan
pkgs.jre_minimaldanjlinkUkuran image menjadi 161MB, sedikit lebih besar daripada image
demo_jlink. Ini karena JRE menjadi sekitar 90MB setelah benar-benar menyertakan semua modul yang diperlukan untuk menjalankan aplikasi. PemanggilanjdepsdiDockerfile_jlinktidak mendeteksi semua modul, sehingga JRE yang dibuat hanya berisijava.base. Jika JRE minimal saya juga hanya memasukkanjava.base, ukuran JRE menjadi sekitar 50MB, dan image container yang rusak menjadi 117MB menurut PodmanSaya juga menghapus
copyToRootyang keliru pada pemanggilandockerTools.buildImage. Hanya dengan konteks string diconfig.Cmd, app sudah masuk ke image, tetapi kode sebelumnya menyalin app sekali lagi. Selain itu, saya mengubahnya kedockerTools.buildLayeredImageagar setiap store path dimasukkan ke layer image terpisah; ini bagus untuk skalabilitas ruang saat berbagi dependensi di antara beberapa image container, tetapi tidak berpengaruh pada eksperimen satu imageYang tersisa sebagian besar adalah optimasi ukuran JRE.
glibcadalah dependensi terbesar berikutnya, sekitar 30MB, tampaknya karena Nixpkgs membangun glibc agar mendukung banyak locale dan encoding karakter. Saya tidak tahu apakah memungkinkan, atau praktis, untuk memisahkannya menjadi derivation atau output tersendiri agar bisa dipilih. Jika beberapa image dibuat dengandockerTools.buildLayeredImage, dengan asumsi memakai commit Nixpkgs yang sama, glibc dan dependensi lainnya akan dibagikanhttps://github.com/max-privatevoid/hackernews-docker-challen...
Jika Anda sudah mengadopsi Nix, itu bagus, dan semoga manajemen paket deklaratif seperti Nix atau Guix menjadi lebih luas digunakan
Jika Anda sudah memakai Docker tetapi ingin mengadopsi Nix secara bertahap, ada juga pendekatan dalam presentasi ini: https://youtu.be/l17oRkhgqHE
Alih-alih langsung memindahkan konfigurasi dan build container sepenuhnya ke Nix, Anda bisa mempertahankan Dockerfile sambil membuatnya membangun konfigurasi Nix. Kekurangan terbesarnya adalah layer sama sekali tidak bisa dimanfaatkan, sedangkan kelebihannya adalah Anda bisa mengubah Dockerfile secara bertahap sambil menggunakan ulang infrastruktur atau otomasi Docker yang sudah ada
[1] https://mitchellh.com/writing/nix-with-dockerfiles
Namun saya merasa sebagian besar ketidakreproduktifan itu mungkin karena tidak ada jaminan bahwa salah satu layer Docker akan terus tersedia. Kalau begitu, saya juga penasaran apakah Nix punya jaminan bahwa versi paket akan tetap ada di repositori selamanya
Agak di luar topik, tetapi ilustrator yang membuat gambar slide ini, Annie Ruygt, juga membuat logo dan art brand untuk dua startup YC, RethinkDB(rethinkdb.com) dan Pachyderm(pachyderm.io)
Ia pernah bekerja di Pachyderm, dan Pachyderm adalah perusahaan yang didirikan oleh mantan engineer RethinkDB. Karyanya benar-benar bagus
Belum lama ini, atas rekomendasi tim infrastruktur, saya menghabiskan sekitar setengah hari mencoba membangun image dasar CI dengan Nix, tetapi image-nya sangat besar dan sebagian tidak berjalan karena masalah linking
Yang terutama menjengkelkan adalah saat membuat image multi-arsitektur, ia mencoba benar-benar menjalankan sesuatu dari arsitektur lain, dan hanya mendukung virtualisasi hardware qemu. Mesin build dan workstation kami adalah VM, jadi tidak punya itu, meskipun ada
binfmt-misc. Kalau ia fork/execmkdirarm64 untuk membuat/tmp, mungkin akan berjalan, tetapi layer Docker hanyalah file tar, jadi direktori bisa dibuat seperti di bawah iniecho "tmp uid=0 gid=0 time=0 mode=0755 type=dir" | bsdtar -cf - @-Layer persis ini kemungkinan besar sudah ada di suatu tempat, sehingga pengguna bahkan mungkin tidak perlu mengunduhnya
Setiap kali mencoba Nix, saya merasa beberapa bulan lagi ia akan bisa saya pakai secara rutin. nixpkgs memiliki hampir semua paket yang saya inginkan dan terpasang dengan baik di workstation. Namun kebutuhan seperti “perlu bash, python, build-essential, Bazel” rasanya bukan tujuan dari Docker image builder. Untuk sekadar memasukkan satu binary Go ke dalam image Docker, Nix tidak diperlukan. Ambil distroless dan masukkan aplikasi ke file tar, maka itu sudah menjadi container. Secara pribadi saya memakai
rules_ocidari Bazel; secara internal yang dilakukan juga kira-kira sebatas itu, dengan sedikit kecerdasan tambahan untuk membangun binary bagi beberapa arsitektur, membuat YAML image index, lalu mendorongnya ke registryTentu saja file build paketnya harus mendukung hal itu. Pernyataan bahwa qemu hanya mendukung virtualisasi hardware juga tampaknya tidak tepat. qemu juga bisa digunakan untuk arsitektur yang hanya memungkinkan emulasi software
Contoh minimal dibahas di sini: https://discourse.nixos.org/t/how-do-i-get-a-shell-nix-with-...
Saya tidak sampai ingin mengatakan bahwa ini seharusnya sesederhana memakai
pkgCross, tetapi saya penasaran masalah konkret apa yang Anda temui dalam proses umumnyahttps://nix.dev/tutorials/cross-compilation.html
Saya sudah memakainya selama bertahun-tahun di beberapa proyek, tetapi jika ukuran menjadi masalah, dengan cara yang disebutkan dalam tulisan, Anda bisa membuat image yang sangat kecil dan hanya berisi hal-hal yang ditentukan
[1] https://hub.docker.com/r/nixos/nix/tags
Saya bahkan memakai musl, membangun image paling kecil dibandingkan alat lain mana pun secara cepat dan konsisten di CI, dan caching juga berjalan baik. Saya kurang paham apa yang dimaksud dengan ada sesuatu yang dijalankan
buildFHSEnvuntuk mendukung binary pihak ketiga yang anehSepertinya Nix membutuhkan lebih banyak tulisan yang menjelaskan cara bermigrasi secara halus dan bertahap dari sistem yang sudah ada
Sebagai platform engineer, saya ingin menyukai Nix, tetapi itu tidak mudah bagi semua orang
Menurut saya pengalaman pengembangnya juga masih cukup buruk. Misalnya, saya lebih menyukai pengalaman pengembang devbox karena bisa menambahkan paket seperti
devbox add python@3.11Melihat
flake.nixsepanjang 120 baris, sulit juga untuk mengatakan bahwa itu benar-benar “lebih mudah”https://github.com/Xe/douglas-adams-quotes/blob/main/flake.n...
Flake yang ditautkan mendefinisikan cara membangun binary Go, mendefinisikan image Docker yang memakai binary itu sebagai entry point, dan juga mendefinisikan modul NixOS yang membuat layanan systemd untuk menjalankan binary Go tersebut. Selain itu, ia juga menyertakan pengujian NixOS untuk memastikan modul NixOS itu membuat layanan systemd sesuai harapan
Framework pengujian NixOS cukup mengesankan, dan pengujiannya berjalan di dalam VM QEMU yang menjalankan NixOS bersama-sama. Yang relevan dengan artikel yang ditautkan hanyalah definisi binary Go dan image Docker, serta sebagian boilerplate di sekitarnya
Selain itu, banyak barisnya berkorespondensi 1:1 dengan deskripsi layanan systemd inline, jadi tidak akan hilang apa pun sistem yang dipakai. Di dalamnya juga ada cara yang keren untuk mendeklarasikan beberapa sistem lewat override
Contoh ini lebih dekat dengan “mari melakukan hal sepele seperti dalam proyek besar yang serius”, dan jika diperlakukan sebagai pekerjaan sekali pakai, sepertinya bisa dipangkas menjadi sekitar 40 baris
Binary dan file konfigurasi itu adalah bentuk yang paling mendekati “flat pack” yang bisa didapat di Linux, dan contoh ini menunjukkan dengan baik apa yang kita lewatkan antara melihat hutan dan pohonnya
Guix juga punya opsi Docker yang mudah dan bagus bernama
guix pack -f dockerGuix juga punya keunggulan karena memakai bahasa yang sudah digunakan, yaitu Guile/Scheme, alih-alih bahasa khusus buatannya sendiri
[1] https://guix.gnu.org/manual/en/html_node/Invoking-guix-pack....