ในโลกของ Software Development ปัญหา "It works on my machine" เป็นเรื่องที่เจอกันทุกวัน Dependency version ไม่ตรง, ระบบ Build ไม่ Reproducible, Environment ของแต่ละคนต่างกัน Nix เกิดมาเพื่อแก้ปัญหาเหล่านี้ทั้งหมด
บทความนี้จะพาทำความรู้จัก Nix ตั้งแต่พื้นฐาน Package Manager ไปจนถึง NixOS, Flakes และการใช้งานจริงในทีม Development ปี 2026
Nix คืออะไร?
Nix คือ Purely Functional Package Manager ที่ออกแบบมาเพื่อให้การจัดการ Package และ Build เป็นแบบ Reproducible ทุกครั้ง สร้างโดย Eelco Dolstra ในปี 2003 โดยแนวคิดหลักคือ:
- Purely Functional: ทุก Package ถูก Build จาก Expression ที่กำหนดชัดเจน ไม่มี Side Effect
- Reproducible: Build ซ้ำกี่ครั้งก็ได้ผลเหมือนกันทุกครั้ง
- Declarative: ประกาศว่าต้องการอะไร ไม่ใช่สั่งทีละขั้น
- Rollback: ย้อนกลับ Version ได้ทันทีเสมอ
- Multiple Versions: ติดตั้ง Package หลาย Version พร้อมกันได้โดยไม่ Conflict
Nix vs Package Manager อื่น
| Feature | apt/yum | Homebrew | npm/pip | Nix |
|---|---|---|---|---|
| Reproducible | ไม่ | ไม่ | บางส่วน | ใช่ |
| Multiple Versions | ยาก | ไม่ | Project-level | ใช่ |
| Rollback | ไม่ | ไม่ | ไม่ | ใช่ |
| Cross-platform | Linux | macOS | ทุก OS | Linux/macOS |
| Declarative | ไม่ | ไม่ | package.json | ใช่ |
| Atomic Upgrades | ไม่ | ไม่ | ไม่ | ใช่ |
ติดตั้ง Nix
# Linux / macOS (Single-user)
sh <(curl -L https://nixos.org/nix/install)
# Linux (Multi-user — แนะนำ)
sh <(curl -L https://nixos.org/nix/install) --daemon
# เปิด Flakes (ใส่ใน ~/.config/nix/nix.conf)
experimental-features = nix-command flakes
# ทดสอบ
nix --version
nix run nixpkgs#hello
Nix Language พื้นฐาน
Nix มีภาษาเฉพาะของตัวเอง เป็น Purely Functional, Lazy Evaluation คล้าย Haskell แต่เรียบง่ายกว่ามาก:
# Primitive Types
"hello" # String
42 # Integer
true # Boolean
null # Null
/etc/nixos # Path
# Attribute Sets (เหมือน Object/Dict)
{
name = "my-app";
version = "1.0";
meta = {
description = "My application";
};
}
# Functions (Lambda)
x: x + 1 # รับ 1 argument
x: y: x + y # Curried function
{ name, version }: name # Destructuring
# Let bindings
let
x = 10;
y = 20;
in x + y # = 30
# With expression
with pkgs; [ nodejs python3 git ]
# เทียบเท่า [ pkgs.nodejs pkgs.python3 pkgs.git ]
# If-else
if x > 0 then "positive" else "non-positive"
# Import
import ./my-file.nix
Derivation — หัวใจของ Nix
Derivation คือ Blueprint สำหรับ Build Package ใน Nix ทุก Package ใน Nixpkgs คือ Derivation:
# ตัวอย่าง Derivation อย่างง่าย
{ pkgs ? import <nixpkgs> {} }:
pkgs.stdenv.mkDerivation {
pname = "my-app";
version = "1.0.0";
src = ./src;
buildInputs = with pkgs; [ gcc gnumake ];
buildPhase = ''
make
'';
installPhase = ''
mkdir -p $out/bin
cp my-app $out/bin/
'';
}
/nix/store/ โดยมี Hash ของ Input ทั้งหมดเป็น Prefix เช่น /nix/store/abc123...-nodejs-20.11.0/ ทำให้หลาย Version อยู่ร่วมกันได้
nix-shell — Development Environments
nix-shell สร้าง Temporary Shell ที่มี Dependency ครบตามที่กำหนด พอออกจาก Shell ทุกอย่างหายไป:
# Ad-hoc: เรียกใช้ Package ชั่วคราว
nix-shell -p nodejs python3 git
# shell.nix — กำหนด Dev Environment
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
python311
postgresql_16
redis
git
curl
];
shellHook = ''
echo "Dev environment loaded!"
export DATABASE_URL="postgres://localhost/mydb"
'';
}
# ใช้งาน
cd my-project
nix-shell # โหลด shell.nix อัตโนมัติ
Flakes — Nix ยุคใหม่
Flakes คือระบบใหม่ที่ทำให้ Nix Project มี Structure ชัดเจน มี Lock File (เหมือน package-lock.json) และ Reproducible 100%:
# flake.nix
{
description = "My project dev environment";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
nodejs_20
nodePackages.typescript
python311
docker-compose
];
};
packages.default = pkgs.buildNpmPackage {
pname = "my-app";
version = "1.0.0";
src = ./.;
npmDepsHash = "sha256-xxxx";
};
}
);
}
# คำสั่ง Flakes
nix develop # เข้า Dev Shell (แทน nix-shell)
nix build # Build Package
nix run # Build + Run
nix flake update # Update flake.lock
nix flake show # แสดง Outputs ทั้งหมด
nix flake check # ตรวจสอบ Flake
NixOS — Declarative Operating System
NixOS คือ Linux Distribution ที่ Configuration ทั้งระบบเขียนเป็น Nix Expression ใน File เดียว:
# /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
# Boot
boot.loader.grub.enable = true;
# Network
networking.hostName = "my-server";
networking.firewall.allowedTCPPorts = [ 80 443 22 ];
# Users
users.users.dev = {
isNormalUser = true;
extraGroups = [ "wheel" "docker" ];
packages = with pkgs; [ vim git firefox ];
};
# Services
services.nginx.enable = true;
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
};
services.docker.enable = true;
# System Packages
environment.systemPackages = with pkgs; [
wget curl htop tmux
];
system.stateVersion = "24.11";
}
# Apply Configuration
sudo nixos-rebuild switch # Apply ทันที
sudo nixos-rebuild test # ทดสอบก่อน (ไม่ Set เป็น Default Boot)
sudo nixos-rebuild boot # Apply แต่ Boot ครั้งหน้า
# Rollback
sudo nixos-rebuild switch --rollback
# หรือเลือก Generation ตอน Boot
Home Manager — จัดการ Dotfiles
Home Manager ใช้ Nix จัดการ User-level Configuration (dotfiles, user packages):
# home.nix
{ config, pkgs, ... }:
{
home.username = "dev";
home.homeDirectory = "/home/dev";
home.packages = with pkgs; [
ripgrep fd bat eza
lazygit delta
nodejs_20 python311
];
programs.git = {
enable = true;
userName = "My Name";
userEmail = "me@example.com";
delta.enable = true;
extraConfig = {
init.defaultBranch = "main";
pull.rebase = true;
};
};
programs.zsh = {
enable = true;
enableAutosuggestions = true;
oh-my-zsh = {
enable = true;
theme = "robbyrussell";
plugins = [ "git" "docker" "kubectl" ];
};
};
programs.neovim = {
enable = true;
defaultEditor = true;
plugins = with pkgs.vimPlugins; [
telescope-nvim nvim-treesitter
];
};
home.stateVersion = "24.11";
}
Nix + Docker
Nix สร้าง Docker Image ที่เล็กกว่าและ Reproducible กว่า Dockerfile ทั่วไป:
# ใน flake.nix
packages.dockerImage = pkgs.dockerTools.buildImage {
name = "my-app";
tag = "latest";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [
self.packages.${system}.default
pkgs.cacert
];
};
config = {
Cmd = [ "${self.packages.${system}.default}/bin/my-app" ];
ExposedPorts = { "8080/tcp" = {}; };
};
};
# Build Image
nix build .#dockerImage
docker load < result
Nix + CI/CD และ Cachix
Cachix คือ Binary Cache สำหรับ Nix ช่วยให้ CI/CD ไม่ต้อง Build ซ้ำ:
# GitHub Actions with Nix
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
- uses: cachix/cachix-action@v15
with:
name: my-project-cache
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
- run: nix build
- run: nix flake check
devenv และ devbox — Nix ที่ง่ายขึ้น
สำหรับคนที่อยากได้ประโยชน์จาก Nix โดยไม่ต้องเรียนรู้ภาษา Nix ทั้งหมด:
devenv
# devenv.nix
{ pkgs, ... }:
{
packages = [ pkgs.git ];
languages.javascript = {
enable = true;
package = pkgs.nodejs_20;
};
languages.python = {
enable = true;
version = "3.11";
};
services.postgres = {
enable = true;
initialDatabases = [{ name = "mydb"; }];
};
services.redis.enable = true;
pre-commit.hooks = {
eslint.enable = true;
black.enable = true;
};
}
# ใช้งาน
devenv shell # เข้า Dev Environment
devenv up # Start Services (Postgres, Redis)
devbox
# devbox.json
{
"packages": [
"nodejs@20",
"python@3.11",
"postgresql@16",
"redis@7"
],
"shell": {
"init_hook": ["echo 'Welcome!'"],
"scripts": {
"dev": "npm run dev",
"test": "npm test"
}
}
}
# ใช้งาน
devbox shell # เข้า Environment
devbox run dev # Run Script
devbox services up # Start Services
Nix สำหรับทีม — Workflow จริง
# โครงสร้าง Project กับ Nix
my-project/
├── flake.nix # Dev Environment + Build
├── flake.lock # Locked Dependencies
├── src/
├── tests/
└── .envrc # direnv integration
# .envrc (ใช้ร่วมกับ direnv)
use flake
# ทีมทำงาน:
# 1. Clone repo
git clone https://github.com/team/project.git
cd project
# 2. เข้า Dev Environment (อัตโนมัติด้วย direnv)
direnv allow # ครั้งแรกครั้งเดียว
# หรือ
nix develop
# 3. ทุกคนได้ Environment เหมือนกัน 100%!
Nix vs Docker สำหรับ Dev Environments
| ด้าน | Nix | Docker |
|---|---|---|
| Performance | Native speed | Overhead จาก VM/Layer |
| File System | Native | Bind mount (ช้า macOS) |
| Reproducibility | 100% (hash-based) | ขึ้นกับ Base Image |
| Learning Curve | สูง (Nix Language) | ปานกลาง (Dockerfile) |
| IDE Integration | Native (ไม่ต้อง Remote) | ต้อง Dev Containers |
| Production Deploy | NixOS หรือ Nix Docker | มาตรฐาน Industry |
| Ecosystem | 80,000+ packages | Docker Hub |
ข้อดีของ Nix
- Reproducible: Build เมื่อไหร่ก็ได้ผลเหมือนกัน ไม่มี "works on my machine"
- Rollback: ย้อนกลับได้ทุกเมื่อ ทั้ง Package และ OS Configuration
- Multiple Versions: ใช้ Node 18 และ Node 20 พร้อมกันได้ ไม่ Conflict
- Atomic: Upgrade สำเร็จหรือไม่สำเร็จ ไม่มีสถานะครึ่งๆ กลางๆ
- Per-project: แต่ละ Project มี Dependency ของตัวเอง แยกจากกันสมบูรณ์
- Huge Ecosystem: Nixpkgs มี Package มากกว่า 80,000 รายการ ใหญ่ที่สุดในโลก
ความท้าทายของ Nix
- Learning Curve สูง: ภาษา Nix ไม่เหมือนภาษาไหน ต้องเรียนใหม่
- Documentation: กระจัดกระจาย มีหลาย Version (Legacy vs Flakes)
- Error Messages: อ่านยาก Debug ลำบากสำหรับมือใหม่
- Disk Space: /nix/store ใช้พื้นที่เยอะ ต้อง Garbage Collect เป็นระยะ
- macOS Support: ทำงานได้แต่บางอย่างไม่ราบรื่นเท่า Linux
# Garbage Collection — ลบ Package ที่ไม่ใช้
nix-collect-garbage -d # ลบทุก Generation เก่า
nix store gc --max 10G # เก็บไว้ไม่เกิน 10GB
nix store optimise # Deduplicate files
เริ่มต้นใช้ Nix — Step by Step
- ติดตั้ง Nix: ใช้ Official Installer + เปิด Flakes
- ลองใช้ nix run:
nix run nixpkgs#cowsay -- "Hello Nix!" - สร้าง flake.nix: เขียน Dev Shell สำหรับ Project ของคุณ
- ติดตั้ง direnv: ให้ Environment โหลดอัตโนมัติเมื่อ
cdเข้า Project - ลอง devenv/devbox: ถ้ายังไม่อยากเขียน Nix เอง
- สำรวจ Nixpkgs: ค้นหา Package ที่
search.nixos.org
Nix Ecosystem ที่ควรรู้
| เครื่องมือ | หน้าที่ |
|---|---|
Nixpkgs | Repository ของ Package ทั้งหมด (80,000+) |
NixOS | Linux Distro ที่ Declarative ทั้งระบบ |
Home Manager | จัดการ Dotfiles และ User Config |
Cachix | Binary Cache สำหรับ CI/CD |
devenv | Dev Environment แบบง่าย |
devbox | Nix-based Dev Environment (JSON config) |
direnv | Auto-load Environment เมื่อเข้า Directory |
nix-darwin | NixOS-style Config สำหรับ macOS |
สรุป
Nix เป็นเครื่องมือที่ทรงพลังที่สุดสำหรับ Reproducible Builds และ Development Environments ในปี 2026 แม้ Learning Curve จะสูง แต่ผลตอบแทนคุ้มค่ามาก: ไม่มี "works on my machine" อีกต่อไป, ทุกคนในทีมได้ Environment เหมือนกัน 100%, Rollback ได้ทุกเมื่อ
ถ้าคุณเบื่อกับปัญหา Dependency Hell และอยากให้ Build ของคุณ Reproducible จริงๆ ลองเริ่มจาก devbox หรือ devenv ก่อน แล้วค่อยขยับไปใช้ Flakes เต็มรูปแบบเมื่อพร้อม Nix จะเปลี่ยนวิธีที่คุณคิดเกี่ยวกับ Software Development ไปตลอดกาล
