14 KiB
NixOS Homelab Install Guide
이 문서는 yggdrasil, midgard를 NixOS installer USB에서 부팅한 뒤
이 repo를 source of truth로 사용해 최초 설치하는 절차를 설명한다.
기본 원칙:
- 최초 설치는 NixOS installer USB 환경에
root로 SSH 접속해서 진행한다. - 설치 후 운영은
poby사용자와 SSH key로 접속한다. - 대상 머신에서 설정 파일을 직접 고치지 않는다.
- 대상 머신은 디스크 ID와 하드웨어 정보를 조회하는 용도로만 사용한다.
- 실제 설정 변경은 항상 이 Git repo에서 한다.
disko는 대상 디스크를 재파티션/포맷한다. 디스크 선택을 반드시 확인한다.
현재 repo 상태
이 repo는 두 호스트를 가진 flake로 구성된다.
yggdrasil
midgard
공통 설정은 modules/에 있고, 호스트별 설정은 hosts/<host>/에 있다.
설치 전에 반드시 채워야 하는 파일:
hosts/yggdrasil/disko.nix
hosts/yggdrasil/hardware-configuration.nix
hosts/yggdrasil/default.nix
hosts/midgard/disko.nix
hosts/midgard/hardware-configuration.nix
hosts/midgard/default.nix
현재 hosts/<host>/default.nix의 imports는 의도적으로 주석 처리되어 있다.
# imports = [
# ./hardware-configuration.nix
# ./disko.nix
# ];
각 호스트의 disk by-id와 hardware configuration을 채운 뒤에만 이 imports를 활성화한다.
설치 전 준비
워크스테이션에서 확인한다.
cd /Users/kmeatai/Developer/homelab
git status -sb
작업트리가 깨끗한 상태에서 시작하는 것을 권장한다.
필요한 것:
- Nix가 설치된 워크스테이션
- 이 repo
- NixOS installer USB
- 대상 머신의 유선 또는 안정적인 무선 네트워크
poby로 접속할 SSH private key- 대상 머신의 기존 데이터 백업
주의:
- 이 절차는 대상 머신 디스크를 지운다.
- yggdrasil을 먼저 설치하고 검증한 뒤 midgard를 설치한다.
- 동시에 두 머신을 진행하지 않는다.
1. 대상 머신을 installer USB로 부팅
먼저 yggdrasil부터 진행한다.
대상 머신에 NixOS installer USB를 꽂고 부팅한다.
installer shell이 뜨면 대상 머신 콘솔에서 root 비밀번호를 임시로 설정한다.
sudo passwd root
이 비밀번호는 installer live environment에서만 쓰는 임시 비밀번호다. 설치 후 재부팅하면 최종 NixOS 설정이 적용되고 root SSH login은 비활성화된다.
SSH 서버를 시작한다.
sudo systemctl start sshd
대상 머신의 IP 주소를 확인한다.
ip addr
LAN IP를 기록한다.
<YGGDRASIL_INSTALLER_IP>
2. 워크스테이션에서 installer에 SSH 접속 확인
워크스테이션에서 접속한다.
ssh root@<YGGDRASIL_INSTALLER_IP>
접속되면 installer 환경 안에 들어온 것이다.
프롬프트가 헷갈리면 다음 명령으로 현재 머신을 확인한다.
hostname
cat /etc/os-release
확인 후 SSH 세션은 열어둬도 되고, 필요한 명령만 실행한 뒤 나와도 된다.
exit
3. disk by-id 확인
대상 머신 installer shell에서 실행한다.
lsblk -o NAME,SIZE,MODEL,SERIAL,TYPE
ls -l /dev/disk/by-id/
또는 워크스테이션에서 SSH로 직접 실행해도 된다.
ssh root@<YGGDRASIL_INSTALLER_IP> 'lsblk -o NAME,SIZE,MODEL,SERIAL,TYPE; ls -l /dev/disk/by-id/'
목표는 설치할 내부 디스크의 안정적인 by-id 경로를 찾는 것이다.
예시:
/dev/disk/by-id/ata-Samsung_SSD_860_EVO_250GB_S3Z...
/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_...
사용하지 말아야 할 값:
/dev/sda
/dev/nvme0n1
이 이름들은 부팅 순서나 USB 장치에 따라 바뀔 수 있다.
주의:
- USB installer 자체를 대상 디스크로 고르면 안 된다.
- 크기, 모델명, serial을 보고 내부 디스크인지 확인한다.
- 확신이 없으면 여기서 멈추고 다시 확인한다.
4. disko.nix의 placeholder 교체
워크스테이션의 repo에서 hosts/yggdrasil/disko.nix를 연다.
현재는 이런 placeholder가 있다.
device = "/dev/disk/by-id/REPLACE_WITH_YGGDRASIL_DISK_ID";
installer에서 확인한 실제 by-id 경로로 교체한다.
예시:
device = "/dev/disk/by-id/ata-Samsung_SSD_860_EVO_250GB_S3Z...";
이 파일은 다음 레이아웃을 만든다.
GPT partition table
512M EFI System Partition -> /boot, vfat
remaining disk -> /, ext4
이 단계는 아직 설치를 실행하지 않는다. 파일만 수정한다.
5. hardware-configuration.nix 생성
대상 머신 installer shell에서 실행한다.
nixos-generate-config --show-hardware-config
출력 전체를 복사해서 워크스테이션 repo의 파일에 붙여 넣는다.
hosts/yggdrasil/hardware-configuration.nix
기존 placeholder 전체를 생성된 내용으로 교체한다.
워크스테이션에서 바로 파일로 저장하려면 다음처럼 해도 된다.
ssh root@<YGGDRASIL_INSTALLER_IP> \
'nixos-generate-config --show-hardware-config' \
> hosts/yggdrasil/hardware-configuration.nix
주의:
hardware-configuration.nix는 대상 머신에서 생성한 값을 사용한다.- yggdrasil에서 생성한 파일을 midgard에 재사용하지 않는다.
- disko가
/와/boot파일시스템을 선언하므로 생성된 hardware config를 그대로 믿지 말고 검토한다.
hardware-configuration.nix에는 보통 이런 내용이 남으면 된다.
imports = [
(modulesPath + "/installer/scan/not-detected.nix")
];
boot.initrd.availableKernelModules = [ ... ];
boot.initrd.kernelModules = [ ... ];
boot.kernelModules = [ ... ];
boot.extraModulePackages = [ ... ];
nixpkgs.hostPlatform = "x86_64-linux";
hardware.cpu.intel.updateMicrocode = ...;
hardware.cpu.amd.updateMicrocode = ...;
다음 항목은 disko.nix와 중복되거나 installer/live 환경의 값일 수 있으므로
특히 확인한다.
fileSystems."/"
fileSystems."/boot"
swapDevices
이 repo에서는 /와 /boot는 disko.nix가 담당한다. swap은 modules/swap.nix의
zram swap이 담당한다. 따라서 hardware config에 위 항목이 들어 있다면 왜 필요한지
확실할 때만 남긴다.
6. host default.nix imports 활성화
워크스테이션 repo에서 hosts/yggdrasil/default.nix를 연다.
주석 처리된 imports를 활성화한다.
변경 전:
# imports = [
# ./hardware-configuration.nix
# ./disko.nix
# ];
변경 후:
imports = [
./hardware-configuration.nix
./disko.nix
];
이제 yggdrasil flake config가 실제 하드웨어 설정과 디스크 레이아웃을 포함한다.
7. 설치 전 로컬 검토
워크스테이션에서 변경 사항을 확인한다.
git diff -- hosts/yggdrasil
특히 다음을 확인한다.
hosts/yggdrasil/disko.nix
device가 실제 내부 디스크 by-id인지
hosts/yggdrasil/hardware-configuration.nix
yggdrasil installer에서 생성한 내용인지
hosts/yggdrasil/default.nix
imports가 활성화되었는지
Nix 문법만 가볍게 확인할 수 있다.
nix-instantiate --parse hosts/yggdrasil/default.nix >/dev/null
nix-instantiate --parse hosts/yggdrasil/disko.nix >/dev/null
nix-instantiate --parse hosts/yggdrasil/hardware-configuration.nix >/dev/null
flake.lock이 아직 없다면 이후 flake 평가 또는 설치 과정에서 생성될 수 있다.
생성되면 설치 성공 후 함께 커밋한다.
8. nixos-anywhere 실행
워크스테이션에서 실행한다.
nix run github:nix-community/nixos-anywhere -- \
--flake .#yggdrasil \
root@<YGGDRASIL_INSTALLER_IP>
워크스테이션의 Nix에서 flakes가 꺼져 있다는 에러가 나면 같은 명령에 experimental features를 명시한다.
nix --extra-experimental-features "nix-command flakes" \
run github:nix-community/nixos-anywhere -- \
--flake .#yggdrasil \
root@<YGGDRASIL_INSTALLER_IP>
이 명령은 대상 머신에 SSH로 접속해서 다음을 수행한다.
disko 기반 파티션/포맷
NixOS system closure 복사/설치
bootloader 설치
초기 NixOS 설정 적용
중요:
- 이 단계에서 대상 디스크의 기존 데이터는 삭제된다.
- 실행 전 disk by-id를 다시 확인한다.
- 설치 중 에러가 나면 출력 내용을 저장하고 다음 단계로 진행하지 않는다.
9. 설치 후 재부팅과 SSH 확인
설치가 끝나면 대상 머신을 재부팅한다.
USB installer를 제거하고 내부 디스크로 부팅한다.
부팅 후 워크스테이션에서 SSH 접속을 확인한다.
LAN IP 또는 hostname이 잡혀 있으면:
ssh poby@yggdrasil
IP로 먼저 확인해도 된다.
ssh poby@<YGGDRASIL_LAN_IP>
root SSH 접속은 실패해야 정상이다.
ssh root@yggdrasil
password SSH login도 실패해야 정상이다.
접속 후 기본 상태를 확인한다.
hostname
sudo systemctl status sshd
sudo systemctl status tailscaled
zramctl
free -h
df -h
10. Tailscale 로그인
설치 후 poby로 접속한 상태에서 Tailscale을 tailnet에 붙인다.
sudo tailscale up
브라우저 인증 URL이 나오면 인증한다.
인증 후 상태를 확인한다.
tailscale status
tailscale ip
이후에는 Tailscale IP 또는 MagicDNS 이름으로 SSH 접속할 수 있다.
ssh poby@yggdrasil
11. 첫 remote rebuild 테스트
워크스테이션에서 실행한다.
워크스테이션이 macOS일 수 있으므로 build도 Linux 대상 머신에서 수행하도록
--build-host를 명시한다. poby는 wheel이고 Nix trusted user에 포함되므로
remote build와 remote switch에 사용할 수 있다.
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
test \
--flake .#yggdrasil \
--build-host poby@yggdrasil \
--target-host poby@yggdrasil \
--use-remote-sudo
문제가 없으면 switch를 실행한다.
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
switch \
--flake .#yggdrasil \
--build-host poby@yggdrasil \
--target-host poby@yggdrasil \
--use-remote-sudo
이 방식이 설치 이후의 기본 운영 모델이다.
repo 수정
nixos-rebuild test 또는 nix run ...#nixos-rebuild -- test
nixos-rebuild switch 또는 nix run ...#nixos-rebuild -- switch
git commit
12. yggdrasil 변경사항 커밋
설치가 성공하면 워크스테이션에서 변경사항을 확인한다.
git status -sb
git diff -- hosts/yggdrasil flake.lock
커밋한다.
git add hosts/yggdrasil
if [ -f flake.lock ]; then git add flake.lock; fi
git commit -m "configure yggdrasil hardware"
13. midgard 설치
yggdrasil 설치와 검증이 끝난 뒤 midgard를 같은 방식으로 진행한다.
반복할 파일:
hosts/midgard/disko.nix
hosts/midgard/hardware-configuration.nix
hosts/midgard/default.nix
반복할 명령:
sudo passwd root
sudo systemctl start sshd
ip addr
lsblk -o NAME,SIZE,MODEL,SERIAL,TYPE
ls -l /dev/disk/by-id/
nixos-generate-config --show-hardware-config
워크스테이션에서 설치:
nix run github:nix-community/nixos-anywhere -- \
--flake .#midgard \
root@<MIDGARD_INSTALLER_IP>
설치 후 확인:
ssh poby@midgard
sudo tailscale up
tailscale status
zramctl
df -h
remote rebuild 테스트:
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
test \
--flake .#midgard \
--build-host poby@midgard \
--target-host poby@midgard \
--use-remote-sudo
성공하면:
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
switch \
--flake .#midgard \
--build-host poby@midgard \
--target-host poby@midgard \
--use-remote-sudo
커밋:
git add hosts/midgard
if [ -f flake.lock ]; then git add flake.lock; fi
git commit -m "configure midgard hardware"
14. 설치 후 기본 검증 체크리스트
각 호스트에서 확인한다.
hostname
whoami
groups
sudo -n true
systemctl is-active sshd
systemctl is-active tailscaled
tailscale status
zramctl
free -h
df -h
bootctl status
기대값:
whoami -> poby
groups -> wheel, networkmanager 포함
sudo -n true -> 비밀번호 없이 성공
sshd -> active
tailscaled -> active
zramctl -> zram device 표시
/boot -> vfat EFI partition
/ -> ext4 root filesystem
워크스테이션에서 확인한다.
ssh poby@yggdrasil
ssh poby@midgard
root SSH는 실패해야 한다.
ssh root@yggdrasil
ssh root@midgard
15. 롤백 기본
NixOS 설정 변경 후 문제가 생기면 대상 머신에서 이전 generation으로 되돌릴 수 있다.
sudo nixos-rebuild switch --rollback
부팅 자체가 실패하면 부팅 메뉴에서 이전 generation을 선택한다.
16. 다음 단계
두 머신의 base install이 끝난 뒤에만 다음을 진행한다.
sops-nix 실제 secrets 구성
backup 구성
monitoring 구성
Podman 구성
Caddy / DNS / apps
서비스는 하나씩 추가하고, 각 단계마다 다음을 반복한다.
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
test \
--flake .#<host> \
--build-host poby@<host> \
--target-host poby@<host> \
--use-remote-sudo
nix run github:NixOS/nixpkgs/nixos-25.11#nixos-rebuild -- \
switch \
--flake .#<host> \
--build-host poby@<host> \
--target-host poby@<host> \
--use-remote-sudo
git add .
git commit -m "<small focused change>"