AizuDemy

Tutorial Declarative Server Setup Pakai NixOS Flakes di VPS Linux Production

Tutorial Declarative Server Setup Pakai NixOS Flakes di VPS Linux Production
🎧
Dengarkan Artikel Ini
Suara AI Otomatis • 6 mnt baca baca
⚡ TL;DR

Poin Kunci Artikel Ini:

  • Buat file konfigurasi `.sops.yaml` pada root repositori:
  • Seluruh komponen sistem—kernel, modul, layanan , file konfigurasi, hingga paket aplikasi—didefinisikan secara eksplisit sebagai fungsi murni dalam bahasa Nix.
  • NixOS Flakes mengunci seluruh pohon dependensi dalam file menggunakan hash kriptografi.
📋 Daftar Isi Materi Tutup ▴

1. Anatomi Configuration Drift pada Server Linux Production

Configuration drift adalah kondisi saat status riil server VPS melenceng dari dokumentasi atau konfigurasi awal. Penyebab utama: modifikasi manual lewat SSH, instalasi paket ad-hoc menggunakan package manager imperatif (apt, dnf), suntingan langsung pada file di /etc, serta eksekusi skrip pemeliharaan yang tidak terversi.

Dampak configuration drift meliputi:

  • Inabilitas Reproduksi Server: Server sulit direplikasi saat skalabilitas horizontal atau disaster recovery.
  • State Impresisi: Perubahan dependensi tidak tercatat, memicu kegagalan deployment aplikasi.
  • Downtime Tak Terprediksi: Perbedaan pustaka (library) antar-server menyebabkan bug spesifik lingkungan.

NixOS menyelesaikan masalah ini melalui arsitektur deklaratif dan penyimpan terisolasi (Nix Store). Seluruh komponen sistem—kernel, modul, layanan systemd, file konfigurasi, hingga paket aplikasi—didefinisikan secara eksplisit sebagai fungsi murni dalam bahasa Nix. NixOS Flakes mengunci seluruh pohon dependensi dalam file flake.lock menggunakan hash kriptografi. Pendekatan ini menjamin pembentukan status server bersifat deterministik, identik, dan reproducible di VPS mana pun.

2. Arsitektur Repositori NixOS Flakes

Struktur repositori terorganisir memisahkan konfigurasi global, modul spesifik, dan variabel spesifik host. Inisialisasi struktur proyek infrastruktur sebagai berikut:

mkdir -p nixos-config/hosts/vps-prod
cd nixos-config
git init

Susunan direktori standar production:

.
├── flake.nix
├── flake.lock
├── modules/
│   ├── core.nix
│   ├── services.nix
│   └── security.nix
└── hosts/
    └── vps-prod/
        ├── configuration.nix
        ├── disk-config.nix
        └── hardware-configuration.nix

Skema Main Entrypoint: flake.nix

File flake.nix bertindak sebagai entri utama. Deklarasikan dependency channel (nixpkgs) dan skema instance server pada file ini:

{
  description = "Infrastruktur Deklaratif VPS Production NixOS";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
    disko.url = "github:nix-community/disko";
    disko.inputs.nixpkgs.follows = "nixpkgs";
    sops-nix.url = "github:Mic92/sops-nix";
    sops-nix.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { self, nixpkgs, disko, sops-nix, ... }@inputs:
  {
    nixosConfigurations.vps-prod = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [
        disko.nixosModules.disko
        sops-nix.nixosModules.sops
        ./hosts/vps-prod/configuration.nix
      ];
    };
  };
}

Deklarasi Partitioning: hosts/vps-prod/disk-config.nix

Definisikan tata letak partisi disk menggunakan disko untuk automasi format drive:

{
  disko.devices.disk.main = {
    device = "/dev/vda";
    type = "disk";
    content = {
      type = "gpt";
      partitions = {
        boot = {
          size = "1M";
          type = "EF02";
        };
        ESP = {
          size = "512M";
          type = "EF00";
          content = {
            type = "filesystem";
            format = "vfat";
            mountpoint = "/boot";
          };
        };
        root = {
          size = "100%";
          content = {
            type = "filesystem";
            format = "ext4";
            mountpoint = "/";
          };
        };
      };
    };
  };
}

Deklarasi Sistem Server: hosts/vps-prod/configuration.nix

Konfigurasi utama memuat seluruh spesifikasi operasional server:

{ config, pkgs, inputs, ... }:

{
  imports = [
    ./hardware-configuration.nix
    ./disk-config.nix
  ];

  nix.settings = {
    experimental-features = [ "nix-command" "flakes" ];
    auto-optimise-store = true;
  };

  boot.loader.grub = {
    enable = true;
    efiSupport = true;
    efiInstallAsRemovable = true;
  };

  networking = {
    hostName = "vps-prod";
    firewall = {
      enable = true;
      allowedTCPPorts = [ 80 443 22 ];
    };
  };

  services.openssh = {
    enable = true;
    settings = {
      PermitRootLogin = "prohibit-password";
      PasswordAuthentication = false;
      KbdInteractiveAuthentication = false;
    };
  };

  users.users.deploy = {
    isNormalUser = true;
    extraGroups = [ "wheel" ];
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... sysadmin@company.com"
    ];
  };

  security.sudo.wheelNeedsPassword = false;

  services.nginx = {
    enable = true;
    recommendedProxySettings = true;
    recommendedTlsSettings = true;
    virtualHosts."api.company.com" = {
      enableACME = true;
      forceSSL = true;
      locations."/".proxyPass = "http://127.0.0.1:8080";
    };
  };

  security.acme = {
    acceptTerms = true;
    defaults.email = "admin@company.com";
  };

  environment.systemPackages = with pkgs; [
    git
    curl
    htop
    tmux
    ripgrep
    jq
  ];

  system.stateVersion = "23.11";
}

3. Automated Provisioning via nixos-anywhere

Alur bootstrap NixOS ke VPS ber-OS Linux standar (Debian/Ubuntu) tanpa akses ISO fisik:

Langkah 1: Pengujian SSH dan Identifikasi Target

Pastikan akses SSH root ke VPS target aktif:

ssh root@IP_ADDRESS_VPS "uname -a"

Langkah 2: Eksekusi nixos-anywhere

Jalankan nixos-anywhere dari mesin lokal. Skrip ini mengunggah image kexec kustom ke memori VPS, mempartisi ulang disk sesuai spesifikasi disko, menginstal NixOS, dan melakukan reboot otomatis:

nix run github:nix-community/nixos-anywhere -- \
  --flake .#vps-prod \
  root@IP_ADDRESS_VPS

Proses instalasi selesai saat SSH root berbasis sertifikat NixOS dapat diakses.

4. Manajemen Secret Terenkripsi Menggunakan sops-nix

Kode Nix yang tersimpan pada Git bersifat publik/semi-publik. Rahasia (credential, token, SSH private key) tidak boleh ditulis langsung di file .nix karena seluruh isi file .nix tersimpan world-readable di Nix Store (/nix/store).

Pengaturan Enkripsi Age

  1. Generate key pair menggunakan age di mesin lokal:
  2. age-keygen -o ~/.config/sops/age/keys.txt
  3. Ekstrak public key dari file keys.txt.
  4. Buat file konfigurasi `.sops.yaml` pada root repositori:
  5. creation_rules:
      - path_regex: secrets\.yaml$
        key_groups:
          - age:
              - "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Membuat File Secret Terenkripsi

Buat file secrets.yaml:

sops secrets.yaml

Isikan data sensitif:

db_password: SuperSecretPassword123!
api_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Integrasi Secret ke Konfigurasi Server

Sesuaikan hosts/vps-prod/configuration.nix untuk mendenkripsi secret saat runtime ke direktori memori (RAM disk /run/secrets):

{
  sops.defaultSopsFile = ../../secrets.yaml;
  sops.defaultSopsFormat = "yaml";
  sops.age.keyFile = "/var/lib/sops-nix/key.txt";

  sops.secrets.db_password = {
    owner = "deploy";
    group = "users";
  };

  systemd.services.my-app = {
    description = "Production App Service";
    after = [ "network.target" ];
    wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      ExecStart = "${pkgs.nodejs}/bin/node /path/to/app/index.js";
      EnvironmentFile = config.sops.secrets.db_password.path;
      User = "deploy";
    };
  };
}

5. Pengelolaan Generasi, Instant Rollback, dan Garbage Collection

Setiap perubahan konfigurasi yang disebarkan ke NixOS menghasilkan immutable snapshot baru bernama Generation.

Eksekusi Update Konfigurasi

Terapkan perubahan konfigurasi lokal ke server VPS:

nixos-rebuild switch --flake .#vps-prod --target-host root@IP_ADDRESS_VPS

Inspeksi Generasi Sistem

Tampilkan seluruh riwayat generasi di server VPS:

nixos-rebuild list-generations

Mekanisme Rollback Tanpa Downtime

Jika generasi baru mengalami error fatal, kembalikan status sistem secara instan ke generasi sebelumnya:

nixos-rebuild switch --rollback --target-host root@IP_ADDRESS_VPS

NixOS mengubah symlink /run/current-system ke generasi sebelumnya secara atomik dalam orde milidetik tanpa memerlukan reboot sistem.

Manajemen Ruang Disk (Garbage Collection)

Generasi lama memproteksi paket terkait agar tidak terhapus. Hapus rujukan generasi lama dan bersihkan paket tak terpakai untuk membebaskan ruang disk:

# Hapus generasi yang lebih lama dari 14 hari
nix-env --delete-generations +14d --profile /nix/var/nix/profiles/system

# Eksekusi pembersihan store
nix-collect-garbage -d

# Optimasi link disk murni
nix-store --optimise

Otomatiskan pembersihan melalui configuration.nix:

nix.gc = {
  automatic = true;
  dates = "weekly";
  options = "--delete-older-than 14d";
};

6. Otomasi Deployment CI/CD via GitHub Actions

Gunakan alur integrasi berkelanjutan untuk memvalidasi dan mendeploy konfigurasi secara otomatis.

Workflow File: .github/workflows/deploy.yml

name: "Deploy NixOS Flake"

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Install Nix
        uses: cachix/install-nix-action@v25
        with:
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Validate Flake Syntax
        run: nix flake check

      - name: Setup SSH Key
        uses: webfactory/ssh-agent@v0.9.0
        with:
          ssh-private-key: ${{ secrets.VPS_SSH_PRIVATE_KEY }}

      - name: Deploy to Production VPS
        run: |
          nix run github:serokell/deploy-rs -- .#vps-prod

7. Checklist Evaluasi Infrastruktur Deklaratif

FaseItem PemeriksaanKriteria Kelayakan
CodebaseFlake LockFile flake.lock masuk versi kontrol Git.
KeamananSecret Zero-LeakTidak ada plain-text secret di repositori atau Nix store.
JaringanHardened SSHAkses root via kata sandi dinonaktifkan total.
OperasionalAutomated GCPembersihan nix-garbage berjalan terinterval via systemd timer.
RecoveryRollback VerificationGenerasi terdahulu terverifikasi dapat diaktifkan saat kegagalan build.

Penerapan NixOS Flakes memindahkan pengelolaan infrastruktur VPS dari paradigm imperatif manual ke standar software engineering yang terukur, reproducible, dan aman.

📖 Artikel Terkait