Part 1 NixOSをinstall (👈 この記事)
Part 2 deply-rsでNixOS Configurationを適用
Part 3 ragenixでsecret管理
Part 4 opentelemetry-collectorとopenobserveでmetricsを取得
Part 5 CPUの温度をmetricsとして取得
本記事はNixOSとRaspberry Piで自宅serverをはじめる記事のPart 1です。 まずはRaspberry PiにNixOSをinstallするところから始めていきます。
先日、Raspberry Pi 5が発表されましたが、本記事で利用するのはRaspberry Pi 4 Model Bです。RAMは4GBですが、8にすればよかったと思っています。台数は4で始めました。
Part 1では、4台のRaspberry Pi(以下raspi)に手元のmachineからssh接続できるところまで行います。sshできるようになれば今後の設定の変更はdeploy-rsを利用できるので、sshして設定を変更といった作業がなくなります。
実際に自分のraspiの管理はこのrepoで行っています。
準備するもの
- Raspberry Pi
- 電源
- Router/Switchへ接続するためのLANケーブル
- SD card(raspi分)
- USBキーボード
- モニター(Micro HDMI接続)
キーボードとモニターは初回設定時に必要です。
LANケーブルは無線LAN利用する場合は不要です。今回は有線のみ使用。
NixOS imageをSD Cardに書き込む
基本的にはnix.devのInstalling NixOS on a Raspberry Piにしたがって進めていきます。
NixOS imageの取得
まずimageを取得してきます。imageはこちらから最新のものを選びました。
SD Cardへの書き込み
以下のcommandを実行してからhost machineにSD cardを差し込みます。
dmesg --follow
[ 3381.230145] mmc0: cannot verify signal voltage switch
[ 3381.334038] mmc0: new ultra high speed SDR104 SDXC card at address 59b4
[ 3381.349488] mmcblk0: mmc0:59b4 SD128 119 GiB
[ 3381.399498] mmcblk0: p1
これでSD cardが/dev/mmcblk0
に対応することがわかりました。
さきほど取得したimageを書き込みます。
of=/dev/
はdmesg
の出力に対応させます。
Raspberry Piの設定
raspiにsshする際に利用するkey pairを作成します。
次にraspiに配布する/etc/nixos/configuration.nix
をhost上で作成します。
自分は以下のように設定しました。
{ config, pkgs, lib, ... }:
let
user = "ymgyt";
password = "password";
hostname = "rpi4-01";
in {
boot = {
kernelPackages = pkgs.linuxKernel.packages.linux_rpi4;
initrd.availableKernelModules = [ "xhci_pci" "usbhid" "usb_storage" ];
loader = {
grub.enable = false;
generic-extlinux-compatible.enable = true;
};
};
fileSystems = {
"/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
options = [ "noatime" ];
};
};
networking = {
hostName = hostname;
defaultGateway = "192.168.10.1";
nameservers = [ "8.8.8.8" ];
interfaces.end0.ipv4.addresses = [ {
address = "192.168.10.150";
prefixLength = 24;
} ];
wireless = {
enable = false;
};
};
environment.systemPackages = with pkgs; [ helix git ];
services.openssh.enable = true;
users = {
mutableUsers = false;
users."user" = {
isNormalUser = true;
password = password;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1l...EgT3Ma ymgyt"
];
};
};
security.sudo.wheelNeedsPassword = false;
hardware.enableRedistributableFirmware = true;
system.stateVersion = "23.11";
}
{
networking = {
hostName = hostname;
defaultGateway = "192.168.10.1";
nameservers = [ "8.8.8.8" ];
interfaces.end0.ipv4.addresses = [ {
address = "192.168.10.150";
prefixLength = 24;
} ];
wireless = {
enable = false;
};
};
netroking.hostName
でhostnameを指定します。rpi4-{01,02,03,04}
のように指定しました。
netroking.defaultGateway
は環境の設定にあわせます。
raspiを外部に公開する際にrouterでportのmappingを設定したかったので、raspiのipを固定するようにしました。また、無線LANは無効にしました。
sshの設定は以下です。
{
services.openssh.enable = true;
users = {
mutableUsers = false;
users."user" = {
isNormalUser = true;
password = password;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1l...EgT3Ma ymgyt"
];
};
};
passwordは無効にしてもよいと思いますが最初は有効にしてました。
users.users.ymgyt.openssh.authorizedKeys.keys
にさきほど生成したkey pairの公開鍵を登録します。
作成したconfiguration.nix
をraspiから取得できるようにfile serverを立ち上げました。
今回はsfz
を利用しましたが、なんでも良いです。
ここからはさきほど書き込んだSD Cardをraspiに差し込んでraspi側を操作します。 host machineのprivate addressが192.168.10.10という前提です。
次にfirmwareのupdateを実施しました。
BOOTFS=/mnt FIRMWARE_RELEASE_STATUS=stable
最後に再起動します。
nixos-rebuild boot
systemctl reboot
これで上記のnetwork interfaceやsshの設定が適用されるので以下のようにhost machineからsshできれば成功です。
この手順を残りの3台でも繰り返しました。
変更するのはconfiguration.nix
のhostnameとnetwork interfaceの箇所です。
確認
4台の設定が完了したので、確認してみます。
まずhost名でsshできるように./etc/ssh.config
を作成します。
Host rpi4-01
Hostname 192.168.10.150
Host rpi4-02
Hostname 192.168.10.151
Host rpi4-03
Hostname 192.168.10.152
Host rpi4-04
Hostname 192.168.10.153
Host rpi4-*
User ymgyt
ForwardAgent yes
StrictHostKeyChecking no
配置したsshはssh-add
してある前提です。
次にraspiそれぞれにsshするのは面倒なのでssh用のzellij layoutを以下のように./etc/rpi.layout.kdl
に作成しました。
layout {
pane_template name="ssh" {
command "ssh"
}
pane size=1 borderless=true {
plugin location="zellij:tab-bar"
}
pane split_direction="vertical" {
ssh {
args "ymgyt@192.168.10.150"
}
ssh {
args "ymgyt@192.168.10.151"
}
}
pane split_direction="vertical" {
ssh {
args "ymgyt@192.168.10.152"
}
ssh {
args "ymgyt@192.168.10.153"
}
}
pane size=2 borderless=true {
plugin location="zellij:status-bar"
}
}
これで以下のcommandを実行すると各raspiにsshした状態のtabが開きます。
zellijのdefaultのkeybindで、Ctrl + t, sでsync modeになりtabのpanelそれぞれに一度に入力できます。
以下のようにsshできていれば成功です。
Part 2ではraspiの設定をflakeで管理して、host machineから変更を適用できるようにします。