$30 off During Our Annual Pro Sale. View Details »

Functional, Declarative and Modular System Environment 
with Nix and NixOS

Functional, Declarative and Modular System Environment 
with Nix and NixOS

身為長年的 Linux 使用者,你是否覺得維護作業系統環境是一大困擾?無論是那些套件服務的組態相依、或者那堆針對各個程式打的 patch,這些散落各處、無法被管理或重現的設定是否讓你徹夜難眠:哪天要搬系統怎麼辦?環境壞了是不是很難修?會不會有人偷偷動了我的設定?

又或者你是開發者,常常苦於為新機器設定開發環境都要花上近一整天、或是不同專案倚賴於不同系統套件不知道該如何解決。

Nix 或許可以解決你的煩惱!本議程將簡單介紹 Nix 套件管理工具以及 NixOS 的基本概念:Nix Store、Nix Language、Nix Derivation、Nixpkgs、NixOS、nix-env,來看看 "Purely Functional"、"Declarative" 的 Nix 套件管理工具以及 NixOS 如何解決系統環境問題吧!

個人套件集與 NixOS 設定檔:

- https://github.com/zetavg/nix-packages
- https://github.com/zetavg/nixos-configs

## 參考資料

- [Nix Pills](https://nixos.org/nixos/nix-pills/)
個人最推薦的入門指南,共有 20 篇短篇文章,從安裝、基本使用、原理,一路涵蓋到語言、如何寫套件、一些架構和設計模式,不僅教你如何用 Nix,讀完之後還能任意暴改你的系統以及包裝你自己的 package。
- [Continuous integration for iOS with Nix and Buildkite - Pinterest Engineering](https://medium.com/@Pinterest_Engineering/continuous-integration-for-ios-with-nix-and-buildkite-ef5b36c5292d)
Pinterest 的工程師分享他們如何用 Nix 來統一他們 mobile app 在開發者的機器以及 CI 上的環境,並用 [Buildkite](https://buildkite.com/) 這套 CI Interface as a Service 來打造他們的 CI 環境。
- [Nix: Haskell Concepts for Package Management - HackerNoon.com](https://hackernoon.com/nix-haskell-concepts-for-package-management-65830ac89659)
介紹 Nix 如何利用 Functional、Declarative 的特性,解決傳統系統環境容易被污染、無法版本控管等問題,也提出了每次都要從原始碼編譯很耗時(但我想 binary cache 可以解決這個問題,現在也有很方便的 binary cache as a service,CI 也可以用 Hydra 來獨立測試每個單元,因此除了像是 node 的 npm 一個程式 depend on 數千個 package 會造成就算有 cache 但用正常的方式 handle 數千個 deps 的計算量就很大會慢之外,不算太大的問題)的問題。
- [Eelco Dolstra 在荷蘭烏特勒支大學的博士論文](https://nixos.org/~eelco/pubs/phd-thesis.pdf)
是 Nix 套件管理工具的前身 ([Nix Community - Academia - NixOS Wiki](https://nixos.wiki/wiki/Nix_Community#Academia)) 。
- [Cheatsheet - NixOS Wiki](https://nixos.wiki/index.php?title=Cheatsheet&useskin=vector)
- [How we use Nix at IOHK - Input Output](https://iohk.io/blog/how-we-use-nix-at-iohk/)

## 社群

- [r/NixOS on Reddit](https://www.reddit.com/r/NixOS/)

Pokai Chang

August 17, 2019
Tweet

More Decks by Pokai Chang

Other Decks in Technology

Transcript

  1. ! # @zetavg
 fb.me/pokaichang72 Functional, Declarative and Modular System Environment

    
 with Nix and NixOS
  2. Hi !

  3. ! # @zetavg
 fb.me/pokaichang72
 皰玡㳓 Pokai Chang

  4. ! # @zetavg
 fb.me/pokaichang72
 speakerdeck.com/zetavg 皰玡㳓 Pokai Chang

  5. Functional Programming

  6. 礍ᒊ

  7. None
  8. None
  9. /ๅ碝懿袅.txt

  10. /ๅ碝懿袅.txt

  11. VPS

  12. apt-get install blablabla vi /etc/nginx/conf.d/default.conf patch and recompile nginx 独

  13. /ๅ碝懿袅.txt ݈憎ᶎЎ聲๏݋

  14. Software Development

  15. Develop Environment ▪ Your project still have some system dependencies.

    ▪ How to write instructions for setting up the develop environment? ▪ Write automated scripts instead of instructions. ▪ The script can act as documentation.
 (A kind of doc that you can get benefit from without reading it.) ▪ Forgot to check/install something...
 (Especially when you added or updated some dependencies) ▪ Script broken on a different OS distribution or package manager. ▪ Spend three days to onboard a new member with a working development environment.
  16. Your Desktop/NB

  17. None
  18. None
  19. Hidden Dependencies e.g. 
 Key Mapping Tool ↓ Window Manager

    ↓
 App Scripting
  20. Patches Everywhere

  21. ???

  22. Software Deployment Problems

  23. Software Deployment Problems

  24. Global Library Dependencies Libraries LibA Applications App1 App2 App3 LibB

  25. Libraries Applications LibA App2 Global Library Dependencies Upgrade of App2

    App1 App2' App3 LibB LibA' $
  26. Global Library Dependencies Libraries LibA Applications App1 App2 App3 LibB

  27. Global Library Dependencies Removal of App3 Libraries LibA Applications App1

    App2 App3 LibB $
  28. None
  29. #PurelyFunctional #Immutable 
 #Declarative #Lazy
 #GarbageCollection
 #PersistedCache

  30. Nix Store Nix Language / Derivation <nixpkgs> NixOS / nix-env

    /nix-shell
  31. Nix Store Nix Language / Derivation <nixpkgs> NixOS / nix-env

    /nix-shell { च๜禊盢
 膏戔懯߽䋊 䋿褬ֵአ {
  32. Nix Store

  33. Nix Store Nix Store glibc-2.27 bash-4.4 zsh-5.7.1 ncurses-6.1 readline-7.0 pcre-8.42

    ghc-8.4.4 nodejs-8.15.1 ruby-2.5.4 python-2.7.15
  34. Nix Store Packages should not depend on global system stuff

    /usr/lib libssl.so App ruby-2.5.4 Global Variables Are Evil!
  35. Nix Store Packages can depend on other packages in the

    Nix Store /usr/lib libssl.so App ruby-2.5.4 Nix Store ruby-2.5.4 openssl-1.0.2
  36. Nix Store Example: bash bash-interactive-4.4 glibc-2.27 bash-4.4 readline-7.0 ncurses-6.1

  37. Nix Store Example: wget wget-1.19.5 glibc-2.27 zlib-1.2.11 openssl-1.0.2 util-linux-2.32.1 libunistring-0.9.10

    pcre-8.42 libidn2-2.0.5
  38. Generated using: nix-store -q --graph $(which bash) Nix Store Real

    Dependency Graph Generated by Nix: bash
  39. Generated using: nix-store -q --graph $(which gcc) Nix Store Real

    Dependency Graph Generated by Nix: gcc
  40. Generated using: nix-store -q --graph $(which ghc) Nix Store Real

    Dependency Graph Generated by Nix: ghc
  41. Nix Store Nix Store Packages Are Read-only upon Build glibc-2.27

    bash-4.4 zsh-5.7.1 ncurses-6.1 readline-7.0 pcre-8.42 ghc-8.4.4 nodejs-8.15.1 ruby-2.5.4 python-2.7.15
  42. Nix Store Reusable Packages bash-interactive-4.4 glibc-2.27 bash-4.4 readline-7.0 ncurses-6.1

  43. Nix Store Reusable Packages bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 ncurses-6.1 readline-7.0

    pcre-8.42
  44. Nix Store Reusable Packages bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43
  45. Nix Store Reusable Packages bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 #Immutable
  46. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43
  47. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 Unused
  48. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 Unused #GarbageCollection
  49. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 GC Roots GC Roots
  50. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 GC Roots GC Roots
  51. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.7.1 ncurses-6.1 readline-7.0

    pcre-8.43 GC Roots GC Roots
  52. Q: How to modify a package?

  53. Q: How to modify a package? A: You don't. You

    create a new one.
  54. Nix Store: Cryptographic Hash Hash
 Function Source Code Dependencies Build

    Script Build Arguments Environment Variables Build Shell Package Name mn4jdnhkz12a6yd6jg6wvb4mqpxf8q1f Cryptographic Hash
  55. None
  56. Cryptographic Hash

  57. Nix Store This is Possible Same Package Name And "Version"

    bash-4.4 bash-4.4 With Patches
  58. Nix Store This is Possible Same Package Name And "Version"

    bash-4.4 bash-4.4 Cryptographic Hashes are different With Patches
  59. Nix Store: Cryptographic Hash Hash
 Function Source Code Dependencies Build

    Script Build Arguments Environment Variables Build Shell Package Name mn4jdnhkz12a6yd6jg6wvb4mqpxf8q1f { Build Inputs Cryptographic Hash
  60. Nix Store: Cryptographic Hash Hash
 Function Source Code Dependencies Build

    Script Build Arguments Environment Variables Build Shell Package Name mn4jdnhkz12a6yd6jg6wvb4mqpxf8q1f { Build Inputs Cryptographic Hash #PurelyFunctional
  61. Nix Language

  62. Nix Language A pure, lazy, functional language

  63. Nix Language The Language used to write expressions 
 that

    produce derivations
  64. Derivation Nix-speak for a package build action, which derives the

    package from its inputs.
  65. Packages are (special) variables in the Nix Language

  66. Your whole software and its dependencies are declared as data

    structure in a programming language
  67. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 default.nix let pkgs = import <nixpkgs> { }; in derivation { name = "hello"; system = "x86_64-linux"; builder = "${pkgs.bash}/bin/bash"; args = [ "-c" '' export PATH="${pkgs.coreutils}/bin:${pkgs.gcc}/bin" mkdir $out gcc "${./hello.c}" -o "$out/hello" '' ]; }
  68. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 default.nix let pkgs = import <nixpkgs> { }; in derivation { name = "hello"; system = "x86_64-linux"; builder = "${pkgs.bash}/bin/bash"; args = [ "-c" '' export PATH="${pkgs.coreutils}/bin:${pkgs.gcc}/bin" mkdir $out gcc "${./hello.c}" -o "$out/hello" '' ]; }
  69. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 default.nix let pkgs = import <nixpkgs> { }; in derivation { name = "hello"; system = "x86_64-linux"; builder = "${pkgs.bash}/bin/bash"; args = [ "-c" '' export PATH="${pkgs.coreutils}/bin:${pkgs.gcc}/bin" mkdir $out gcc "${./hello.c}" -o "$out/hello" '' ]; } Build Inputs
  70. Nixpkgs

  71. ~= stdlib For Nix Language

  72. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 default.nix let pkgs = import <nixpkgs> { }; in derivation { name = "hello"; system = "x86_64-linux"; builder = "${pkgs.bash}/bin/bash"; args = [ "-c" '' export PATH="${pkgs.coreutils}/bin:${pkgs.gcc}/bin" mkdir $out gcc "${./hello.c}" -o "$out/hello" '' ]; } bash from Nixpkgs gcc from Nixpkgs
  73. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 default.nix let pkgs = import <nixpkgs> { }; in derivation { name = "hello"; system = "x86_64-linux"; builder = "${pkgs.bash}/bin/bash"; args = [ "-c" '' export PATH="${pkgs.coreutils}/bin:${pkgs.gcc}/bin" mkdir $out gcc "${./hello.c}" -o "$out/hello" '' ]; } bash from Nixpkgs gcc from Nixpkgs #Lazy
  74. ~= Channel For Nix Package Manager

  75. You can create a custom package collection that adds or

    overrides packages in Nixpkgs https://github.com/zetavg/nix-packages
  76. NixOS

  77. NixOS Linux distribution, build via Nix

  78. NixOS Packages, Kernal, Configurations... are built by Nix

  79. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 configuration.nix { config, pkgs, lib, ... }: { fileSystems."/home" = { device = "/dev/disk/by-label/home"; }; environment.systemPackages = [ pkgs.git pkgs.vim ]; services.nginx = { enable = true; package = pkgs.nginx.overrideAttrs (oldAttrs: { patches = [ (builtins.toFile "patch" '' --- ./src/core/ngx_conf_file.c +++ ./src/core/ngx_conf_file.c @@ -2,10 +2,10 @@ -#define NGX_CONF_BUFFER 4096 +#define NGX_CONF_BUFFER 131072 '') ]; }); virtualHosts."example.com" = { serverAliases = [ "www.example.com" ]; enableACME = true; forceSSL = true; root = someSitePackage.root; }; }; }
  80. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 configuration.nix { config, pkgs, lib, ... }: { fileSystems."/home" = { device = "/dev/disk/by-label/home"; }; environment.systemPackages = [ pkgs.git pkgs.vim ]; services.nginx = { enable = true; package = pkgs.nginx.overrideAttrs (oldAttrs: { patches = [ (builtins.toFile "patch" '' --- ./src/core/ngx_conf_file.c +++ ./src/core/ngx_conf_file.c @@ -2,10 +2,10 @@ -#define NGX_CONF_BUFFER 4096 +#define NGX_CONF_BUFFER 131072 '') ]; }); virtualHosts."example.com" = { serverAliases = [ "www.example.com" ]; enableACME = true; forceSSL = true; root = someSitePackage.root; }; }; } #Declarative
  81. NixOS Whole System in the Nix Store Nix Store nixos-system

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 pcre-8.42 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 etc etc-user.conf nginx.service ... *Lots of stuff are omitted or simplified to fit in this limited space. nginx.conf
  82. NixOS Switch Between System Versions: Update Nix Store nixos-system-xxx-1 nixos-system-xxx-2

    nixos-system-xxx-3 bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space. nixos rebuild --switch
  83. NixOS Switch Between System Versions Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  84. NixOS Switch Between System Versions Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  85. NixOS Switch Between System Versions Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  86. NixOS Multiple Systems Coexist Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3 bash-interactive-4.4

    glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  87. Boot Into a Specific Version

  88. nix-env

  89. Your Shell Environment

  90. None
  91. None
  92. Generations Switch between different nix-env generations

  93. NixOS Switch Between System Versions Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  94. NixOS Switch Between System Versions Nix Store nixos-system-xxx-1 nixos-system-xxx-2 nixos-system-xxx-3

    bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 pcre-8.42 nginx-1.14.2 passenger-6.0.2 pcre-8.43 openssl-1.1.1 libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 ncurses-6.1 readline-7.0 zlib-1.2.11 *Lots of stuff are omitted or simplified to fit in this limited space.
  95. None
  96. nix-shell

  97. For
 Software Development

  98. 1. Get into the shell environment that builds a specific

    package
  99. 2. Write Nix expressions to declare a shell environment and

    jump into it
  100. 2. Write Nix expressions to declare a shell environment and

    jump into it #Declarative
  101. Wrap Up

  102. Nix Store: Cryptographic Hash Hash
 Function Source Code Dependencies Build

    Script Build Arguments Environment Variables Build Shell Package Name mn4jdnhkz12a6yd6jg6wvb4mqpxf8q1f { Build Inputs Cryptographic Hash #PurelyFunctional
  103. Nix Store Reusable Packages bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 #Immutable
  104. NixOS Whole System in the Nix Store nixos-system 42 penssl-1.1.1

    libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 zlib-1.2.11 etc etc-user.conf nginx.service ... *Lots of stuff are omitted or simplified to fit in this limited space. nginx.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 configuration.nix { config, pkgs, lib, ... }: { fileSystems."/home" = { device = "/dev/disk/by-label/home"; }; environment.systemPackages = [ pkgs.git services.nginx = { enable = true; package = pkgs.nginx.overrideAttrs (o patches = [ (builtins.toFile "patch --- ./src/core/ngx_conf_file.c +++ ./src/core/ngx_conf_file.c @@ -2,10 +2,10 @@ -#define NGX_CONF_BUFFER 4096 +#define NGX_CONF_BUFFER 131072 '') ]; }); virtualHosts."example.com" = { serverAliases = [ "www.example.com" #Declarative
  105. NixOS Whole System in the Nix Store nixos-system 42 penssl-1.1.1

    libxslt-1.1.33 libxml2-2.9.9 nginx-1.14.2 zlib-1.2.11 etc etc-user.conf nginx.service ... *Lots of stuff are omitted or simplified to fit in this limited space. nginx.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 configuration.nix { config, pkgs, lib, ... }: { fileSystems."/home" = { device = "/dev/disk/by-label/home"; }; environment.systemPackages = [ pkgs.git services.nginx = { enable = true; package = pkgs.nginx.overrideAttrs (o patches = [ (builtins.toFile "patch --- ./src/core/ngx_conf_file.c +++ ./src/core/ngx_conf_file.c @@ -2,10 +2,10 @@ -#define NGX_CONF_BUFFER 4096 +#define NGX_CONF_BUFFER 131072 '') ]; }); virtualHosts."example.com" = { serverAliases = [ "www.example.com" #Lazy #Declarative
  106. Nix Store Package Removal bash-interactive-4.4 glibc-2.27 bash-4.4 zsh-5.6.2 zsh-5.7.1 ncurses-6.1

    readline-7.0 pcre-8.42 pcre-8.43 GC Roots GC Roots #GarbageCollection
  107. More ▪ Cachix: Nix binary cache as a service ▪

    Hydra: A Nix build farm ▪ NixOps: Use Nix to declaratively deploy infrastructures
  108. Stuff I Done ▪ NixOS on GCP ▪ https://github.com/zetavg/nixos-configs ▪

    https://github.com/zetavg/nix-packages ▪ Phusion Passenger and nginx-mod-passenger ▪ "NPM" implemented with Nix ▪ Patched version of some programms
  109. Recommend Materials ▪ Functional Thursday: Nix and NixOS牧9/5 at Mozilla

    מ嬝玟旰獍ਰ牐 ▪ Nix Pills: https://nixos.org/nixos/nix-pills/
 㮆Ո磧വ萃ጱ獈槹瞲ܖ牧و磪 20 缰Ꭸ缰෈ᒍ牧ℂਞ蕕牏च๜ֵአ牏ܻቘ牧Ӟ ᪠窩荠ک承᥺牏ই֜䌃ॺկ牏Ӟ犚礍䯤޾戔懯秇ୗ牧犋㰍硽֦ই֜አ Nix牧捝 ਠԏ盅螭胼犨఺ู硬֦ጱ羬翄犥现۱蕕֦ᛔ૩ጱ package牐 ▪ Continuous integration for iOS with Nix and Buildkite - Pinterest Engineering
 Pinterest ጱૡ纷䒍獤Ձ犢㮉ই֜አ Nix 㬵翄Ӟ犢㮉 mobile app ࣁ樄咳ᘏጱ秚 瑊犥现 CI Ӥጱ絑ह牧㪔አ Buildkite 蝡ॺ CI Interface as a Service 㬵಑蝨犢 㮉ጱ CI 絑ह牐 ▪ Nix: Haskell Concepts for Package Management - HackerNoon.com
 Օ奧 Nix ই֜ڥአ Functional牏Declarative ጱ粬௔牧薹究㯽翄羬翄絑ह਻ฃ ᤩ࿱礕牏篷ဩ粚๜矒ᓕ缛㺔氂牐 ▪ Eelco Dolstra ࣁ艰葦僂粬ۦඪय़䋊ጱ玡ॊ抷෈
 ฎ Nix ॺկᓕቘૡٍጱ獮蛪牐