NixOS를 설치했다. 그 과정을 정리해보고자 한다.
목차
- 설치한 동기
- NixOS란?
- 설치 과정
- 설치 USB 만들기
- 파티션 및 포맷
- 마운트 및 설정
- 설치
- 후기
설치한 동기
다니는 연구실에 자꾸 nix라는 패키지 매니저를 써야한다고 설파하는 사람이 있는데, 그 사람의 말에 결국 넘어가고 만 것이라고 할 수 있다. 항상 기묘-한 최신의 아무도-안-쓰는 기술을 들고 와서 부딪쳐보는 사람이라서 걸러야 할 이야기는 걸러보려고 하는 편인데 계속 거르다가 이번엔 결국 넘어가고 말았다.
이미 아치 리눅스에 pacman이 잘 돌아가는 상황에서 nix를 깔아봐야 쓸 일이 별로 없으므로 NixOS에 도전해보기로 했다. 가상머신에서 이것저것 해보면서 간을 보려고 했는데 아무래도 가상 디스크와 가상 디스플레이, 가상 사운드로 문제를 해결하는 과정이 실감나지가 않아서 데스크탑을 밀고 바로 NixOS를 깔기로 했다.
NixOS란?
NixOS는 nix 패키지 매니저의 철학을 운영체제로 확장한 리눅스 배포판이다. 그러니 nix에 대해 먼저 알아보는 것이 좋겠다.
nix는 쉽게 말하면 함수형-선언형 패키지 매니저다. 일반적인 패키지 매니저는 내 컴퓨터의 이곳저곳을 마구 건드리기 때문에 패키지끼리 충돌이 나기도 하고, 설정 파일도 여기저기 흩어져 있다. 만약 다른 컴퓨터에서 그 환경을 그대로 구현하려면 패키지를 똑같은 순서로 설치하고 설정 파일도 똑같이 수정해야 하는데... 아주 어려운 일일테다. 또 컴퓨터마다 환경이 조금씩 다르므로 여기서는 되던 설정이 저기서는 안 된다든지 하는 일도 자주 일어난다. nix는 이른바 함수형이다. 설정 파일 하나만 고치면 그 내용에 따라서 언제든 재현가능한 환경이 구성된다. 개발환경을 구성하거나 프로그램을 배포하거나 할 때 아주 유용하다. 환경이 같다고 한다면 되던 것은 항상 되기 때문이다.
NixOS는 nix의 철학을 운영체제의 설정으로 확장한다. 요컨대 함수형 운영체제다. 운영체제의 모든 설정이 하나의 파일에 들어있다. 설정 파일만 같다면 똑같은 환경을 어떤 컴퓨터에서든 재현할 수 있다. 굉장히 달콤한 이야기다. 이를테면 "내 컴퓨터에서는 왜 안됨?"의 상황이 터질 때 되는 사람의 NixOS 설정파일과 안 되는 사람의 NixOS 설정 파일을 비교하면서 디버깅하는 것이 가능하다. 또 내가 설정했던 것들이 다 하나의 설정파일에 모여있다는 점도 유용하다. 예전에 이런 설정을 했었구나 하는 것이 다 남아있는 것이다.
한가지 걱정되는 점은, 대부분 소프트웨어의 설치 스크립트는 전역 파일을 건드린다는 점이다. 일반적으로는 설치할 파일들이 정해져있으니 nix가 알아서 판단을 하지만... opam 같은 이상한 패키지 매니저는 새 패키지를 깔 때마다 잠재적 부수 효과를 만들어낸다. 일종의 가상 환경인 "switch"를 만들어서 써도 소용이 없다. 실제로 opam으로 무언가를 설치하려고 하면 종종 apt 명령어를 호출한다고 한다. 무시무시한 프로그램... 연구실의 그 사람 말에 따르면 이 문제도 대충 해결했다고 한다. 아마 괜찮겠지? 걱정되지만 재미를 위해 써보자. 요즘 재미를 좇는 일이 부쩍 줄었다. 환기가 필요한 타이밍이었다.
설치 과정
설치 과정은 NixOS 매뉴얼을 참고했다. ISO 이미지 받는 시간도 짧고 패키지도 필요한 것들만 깔려서 가벼운 Minimal ISO Image를 받아서 Manual Installation을 진행했다. 모든 설치과정은 셸에서 수행된다. 아무도 안 쓰는 OS를 깔기로 선택한 당신! 이 정도의 난관은 헤쳐나가보길 바란다. 셸에 익숙하고 vim이나 nano를 쓸줄알면 충분히 할 수 있다.
설치 USB 만들기
(매뉴얼) 생각보다 어려운 건 없다.
- 다운로드 페이지에서 Minimal ISO image를 받는다. 두 가지 선택지가 있는데 나는 64-bit Intel/AMD를 받았다. 자기 컴퓨터에 맞는 것 받으면 되겠다.
- USB를 꽂는다. 이때 자동으로 마운트가 된다면 마운트를 모두 해제해야 한다. 예를 들어 USB가
/dev/sdb
로 들어갔다면 아래 명령어를 실행한다. 어느 디바이스로 들어갔는지 잘 모르겠다면lsblk
명령어로 저장장치 목록을 보고 판단할 수 있다.# umount /dev/sdb*
- USB를 굽는다. 예를 들어 아까 받은 파일이
./nixos-minimal.iso
이고 USB가/dev/sdb
로 들어갔다면 다음과 같다.# dd bs=4M conv=fsync oflag=direct status=progress \ if=./nixos-minimal.iso of=/dev/sdb
이하의 과정은 이 USB로 부팅한 뒤에 루트 권한으로 하는 작업들이다.
파티션 및 포맷
리눅스를 설치할 때는 일반적으로 세 개 파티션을 설정해야 한다: 루트, 부트, 스왑. 루트 파티션은 리눅스의 파일시스템이 자리할 곳이다. 말 그대로 루트(/
)에 마운트될 파티션이다. 부트 파티션은 대충 컴퓨터가 켜질 때 펌웨어(BIOS, UEFI 등)가 인식하여 부팅할 수 있는 파티션이다. 스왑 영역은 램을 다 썼을 때 디스크를 램처럼 쓸 수 있는 공간이다. 요즘 컴퓨터에서는 스왑은 필요없다고 하는데 예전에 아치 리눅스를 설치할 때 만들어놓은 게 있어서 그대로 썼다.
그렇다. 나는 파티션을 따로 하지 않았다. 아치 리눅스 깔면서 해놨던 파티션을 그대로 썼다ㅋ
자세한 파티션 과정은 매뉴얼을 참조. 아마 UEFI 기준 매뉴얼대로 하되 자신이 리눅스를 설치한 디스크에 작업하면 될 것이다. 아마 스왑은 설정 안 해도 될텐데 하라고 하니까 그냥 하는 것도 괜찮을 것이다. 매뉴얼에서 벗어나면 피곤해지기 때문에.... 나는 최소한의 용량(1GB)만 할당했다.
내가 설치한 디스크는 /dev/nvme0n1
이라는 이름으로 인식된다. SSD는 저런 이름이 되는듯하다. 세 파티션 /dev/nvme0n1p1
, /dev/nvme0n1p2
, /dev/nvme0n1p3
이 있는데, p1을 부트, p2를 루트, p3를 스왑으로 할당했다.
파티션한 부분들을 초기화하고 파일시스템을 만들어주어야 한다. 이 과정을 포맷이라고 하는 것 같다. 그냥 각 파티션을 각각에 맞는 시스템으로 포맷해주면 된다. (매뉴얼)
# mkfs.ext4 -L nixos /dev/nvme0n1p2
# mkswap -L swap /dev/nvme0n1p3
# mkfs.fat -F 32 -n boot /dev/nvme0n1p1
하다보면 "원래 있던 내용을 지울까요?"라는 느낌의 메시지가 나오는데 "예"로 답하면 된다. 당연하게도 원래 디스크에 있던 내용들과는 작별을 고해야 할 것이다. 또 mkfs.fat 명령어에서는 소문자로 이름 지으면 안 좋다고 하는데 별 상관없는 것 같다.
마운트 및 설정
(매뉴얼) 여기서 UEFI를 기준으로 따라가면 된다.
- 위에서 만든 파티션들을 마운트한다. 스왑도 설정한다. 마운트한 대로 NixOS가 알아서 설정을 해주는 듯하다.
# mount /dev/disk/by-label/nixos /mnt # mkdir -p /mnt/boot # mount -o umask=077 /dev/disk/by-label/boot /mnt/boot # swapon /dev/nvme0n1p3
- 설정 파일을 생성한다.
# nixos-generate-config --root /mnt
- 설정 파일을 고친다. 나는 vim을 사용했다. 설정 파일은
/mnt/etc/nixos/configuration.nix
에 위치한다. 생성된 파일에 대충 주석으로 설명이 되어있는데 내가 고쳤던 것들만 나열을 해본다.
networking.hostName = "joongwon-home"
: hostname 설정... 셸 프롬프트에 매번 뜨는데 ssh를 자주 쓰거나 한다면 내가 지금 어떤 컴퓨터에 있는지를 표시하기 좋다.time.timeZone = "Asia/Seoul"
: 시간대 설정. 나는 한국에 있으니까 서울 기준으로 한다.services.xserver.enable = true
: X 서버가 있어야 GUI 앱들을 쓸 수 있다. 데스크탑이 아니라 서버 컴퓨터라면 없어도 될지도?services.xserver.windowManager.i3.enable = true
: 윈도우 매니저나 데스크탑 매니저가 하나 있어야 한다. 궁금해서 찾아보니 없이 사는 것도 가능은 하다지만... 굳이? 창 크기 조절도 못하는 세상에 일부러 살 필요는 없다. 다른 선택지는 매뉴얼을 참조. plasma5, xfce, gnome 등 익숙한 이름들도 있을 것이다. 나는 윈도우 매니저를 써보고 싶어서 가장 많이 쓴다는 i3를 선택했다. 타일링 방식이라 적응이 좀 필요할 것 같다.
boot.loader.systemd-boot.enable = true
: 이 부분은 생성된 설정에 이미 설정이 되어있지만 꼭 있어야 한다고 하니 한번 더 확인해보자. 부팅 메뉴를 설정하는 부분이다.users.users
: 사용자 설정. 사용자는 명령어로 만들 수도 있고 NixOS 설정으로도 만들 수 있는데 일단 메인으로 쓸 사용자 하나는 설정으로 만들었다. 한번 잘못 설정해서 기본 이름인 alice가 됐었다... 포맷부터 다시 하고 두번째에는 joongwon으로 제대로 설정했다.users.users.joongwon = { isNormalUser = true; extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. packages = with pkgs; [ ]; };
programs.firefox.enable = true
: 아무 주석도 안 달려있지만 파이어폭스는 필요하니까 true로 설정. 찾아보니programs
설정이 가능하다면 아래의 패키지로 직접 까는 것보다 이쪽이 더 간편한 듯하다. (참고: NixOS 포럼 쓰레드)environment.systemPackages = with pkgs; [ vim ]
: vim은 있어야지~! vim이 없어도 nano는 있긴 하다.system.copySystemConfiguration = true
: NixOS 설정파일을 백업해준다고 한다.
설치
모든 설정을 완료했다면 설치하자! 아래 명령을 실행하면 기본적인 파일들이 루트에 복사되고 필요한 패키지가 설치되고 설정도 된다. 마지막에는 루트 패스워드를 설정하게 된다.
# nixos-install
로그인할 유저의 패스워드를 설정하는 것도 잊지 말도록 하자.
# nixos-enter --root /mnt -c 'passwd joongwon'
리부트하면 끝.
# reboot
후기
아치 깔 때 했던 일들이랑 비슷하다. 파티션, 포맷, 파일 설치, 필수 패키지 설치. GUI 설정하는 게 설정 파일 수정으로 되는 건 편리한 것 같다. 뭔가 빠트린 것이 있더라도 크게 걱정할 필요 없다.
- 터미널 에뮬레이터(e. g. Konsole)가 없을 때
Ctrl + Alt + F3을 눌러 tty로 전환할 수 있다. tty는 대충 꺼먼 콘솔 창이다. 여기서 패키지 매니저로 설치하면 해결이다. 대부분의 문제는 tty 선에서 해결된다.
이건 딴 얘기지만, 가끔 절전모드에서 돌아왔는데 데스크탑 매니저가 켜지지 않을 때는 tty로 전환 후systemctl restart sddm
을 두 번 정도 실행하면 해결이 됐었다. 이젠 데스크탑 매니저도 없으니 추억일 뿐이다(제발). sudo
명령어가 없을 때
놀랍게도sudo
는 패키지다. 좀 더 기본적인 명령어는 다른 사용자의 셸로 접속할 수 있는su
. 로그인할 사용자명을 입력하지 않으면 루트로 로그인된다. 당연히 루트 패스워드는 알아두어야 한다.- 부팅이 안 될 때
뭔가 중요한 패키지를 잘못 업그레이드하거나 하면 일어날 수 있다. 이럴 때는 다른 컴퓨터로 라이브 부팅 USB(e. g. 위에서 만든 NixOS USB)를 만들어서 그걸로 부팅하고, 메인 디스크를 마운트해서 문제를 알아보자. 예전에 아치리눅스에서 nvidia 드라이버에 문제가 생겼을 때 이렇게 해결했었다.
NixOS의 경우에는 이전 설정으로 부팅하는 것이 가능하므로 좀 더 쉽게 문제를 다룰 수 있을 것이다. 뭔가 잘 안 된다 싶으면 그냥 되던 설정으로 롤백도 가능하다.
요즘 삶이 무료했는데 재밌는 놀거리를 찾은 것 같다. 현재는 소리가 잘 나오도록 하는 문제를 풀고 있다. 일단은 소리가 들리기는 하는데 나오다 말다 하는 것 같다. 신난다! 말로만 하는 말이 아니라 정말로 신이 난다.