年末からお正月の間帰省したときにWindowsのラップトップを持っていった。しかしWSL2にはUbuntuしか入っておらず、最近デスクトップで使っているNixOSが入っていなかった。そこで試しに構築してみたときのメモ。最低限コーディングができる環境が整った。

(IT系あるあるだけれど)NixOS-WSLの開発はまあまあ早いため、ここに書いてある内容もすぐ陳腐化してしまいそう。

インストール

RepositoryのReleasesからnixos-wsl.tar.gzをDLしてくる

コマンドプロンプト or PowerShell で以下のコマンドを実行

1
2
3
wsl --import NixOS .\NixOS\ nixos-wsl.tar.gz --version 2
wsl -d NixOS
nix-channel --update

Flake化による初回セットアップ

今回はなるべくnix-channelを使わず、flake.nixからなるべく必要なファイルを入れるようにしたい。そのほうが、今後再セットアップするときにそのflakeファイルを指定するだけで環境が構築できることを期待しているため。

とはいえ、現状のNixOSにはVimもGitも入っておらず限界があるので、それはChannelから入手する。まず現時点での最新版のnixosのChannelを登録する。

1
2
sudo nix-channel --add https://nixos.org/channels/nixos-23.11 nixos
sudo nix-channel --update

次にVimとGitを入れる。Vimはテキスト編集のため、Gitはnix-flakeの動作のために必要。

1
nix-shell -p vim git

NixOSで最強のLinuxデスクトップを作ろうUsing nix flakes with NixOSに書かれている内容を参考に進めていく。

まずホームディレクトリに移動し、適当なディレクトリnixos-configを作り、そこにNixOSの設定ファイル(configuration.nix)を持ってくる。

1
2
3
4
cd ~
mkdir nixos-config
cd nixos-config
cp /etc/nixos/* .

flake.nixを作成し以下のようにする。

  • inputsにnixosのリポジトリと、NixOS-WSLのリポジトリを指定する
    • inputsの書き方はattribute setとurl-likeな書き方の2種類がある。url-likeな書き方だとtag指定の方法がわからなかったので、NixOS-WSLのinputに関してはattribute setで書いている
  • nixosSystemの引数としてspecialArgsが指定でき、これでconfiguration.nixに引数を渡せる
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
  inputs = {
    nixos.url = "github:NixOS/nixpkgs/nixos-23.11";
    nixos-wsl = {
      type = "github";
      owner = "nix-community";
      repo = "NixOS-WSL";
      ref = "2311.5.3";
    };
  };

  outputs = inputs: {
    nixosConfigurations = {
      wsl = inputs.nixos.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./configuration.nix
        ];
        specialArgs = {
          nixos-wsl = inputs.nixos-wsl;
        };
      };
    };
  };
}

現在、configuration.nixではWSL用のモジュールをnixos-wsl Channelから取得するようになっている。

1
2
3
> sudo nix-channel --list
nixos https://nixos.org/channels/nixos-23.11
nixos-wsl https://github.com/nix-community/NixOS-WSL/archive/refs/heads/main.tar.gz

もしそのまま実行したいなら、以下のコマンドでビルドが可能。--impore引数をつける必要がある。

1
sudo nixos-rebuild switch --impure --flake .#wsl

しかしこのままだとローカルな環境のChannelに依存することになってしまう。flakeでビルドするときはflakeだけで完結させたいので、Channelを使わないような設定に書き換える。そのために、cpでコピーしてきたconfiguration.nixを編集する。

  • 引数にnixos-wslを追加。これは先ほどflake.nixspecialArgsとして指定したattributeに当たる
  • <nixos-wsl/modules>のところをnixos-wsl.nixosModulesに変える
1
2
3
4
5
6
7
8
9
{ config, lib, pkgs, nixos-wsl, ... }:
{
  ...
  imports = [
    # include NixOS-WSL modules
    nixos-wsl.nixosModules.wsl
  ];
  ...
}

これで、次のように--impure無しでコマンドが実行可能になる。

1
sudo nixos-rebuild switch --flake .#wsl

Flakeの有効化

configuration.nixに以下を追記。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{ config, lib, pkgs, nixos-wsl, ... }:
{
  ...
  nix = {
    settings = {
      experimental-features = ["nix-command" "flakes"];
    };
  };
  ...
}

ユーザの追加

  • configuration.nixで、自分ユーザの設定を追加しておく。
  • 今ログインしているnixosユーザの設定を変えるのは余計なトラブルの元になりそうなので避ける
  • お好みでshellを設定する
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{ config, lib, pkgs, nixos-wsl, ... }:
{
  ...
  wsl.defaultUser = "nixos";

  users.users.ユーザ名 = {
    shell = pkgs.fish;
    isNormalUser = true;
    extraGroups = [ "wheel" ];
  };

  programs.fish.enable = true;

  security.sudo = {
    enable = true;
  };
  ...
}

ビルド後、sudo passwd ユーザ名 でユーザのパスワードを設定しておく。

ユーザを指定してログインしたい場合は、-uをつけてログインが可能。

1
2
(コマンドプロンプト or PowerShell内で)
wsl -d NixOS -u ユーザ名

何か設定を間違えてsudoできなくなってしまったという場合には、rootでログインするという手もあるので覚えておく。

1
2
(コマンドプロンプト or PowerShell内で)
wsl -d NixOS -u root

余談

isNormalUserの指定がなかった場合にビルドしたときのエラー。ありえないくらい親切にエラーを出してくれる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
error:
Failed assertions:
- Exactly one of users.users.bombrary.isSystemUser and users.users.bombrary.isNormalUser must be set.

- users.users.bombrary.group is unset. This used to default to
nogroup, but this is unsafe. For example you can create a group
for this user with:
users.users.bombrary.group = "bombrary";
users.groups.bombrary = {};

- users.users.bombrary.shell is set to fish, but
programs.fish.enable is not true. This will cause the fish
shell to lack the basic nix directories in its PATH and might make
logging in as that user impossible. You can fix it with:
programs.fish.enable = true;

If you know what you're doing and you are fine with the behavior,
set users.users.bombrary.ignoreShellProgramCheck = true;
instead.

home-managerの設定

ユーザを作成したら、一応NixOSの再起動を行い、自分が作ったユーザでログインする。

1
2
wsl --shutdown NixOS
wsl -d NixOS -u ユーザ名

また設定ファイルを掻くので、gitをvimを入れておく。

1
nix-shell -p git vim

先程作った設定ファイルを持ってくる

1
2
sudo mv -r /home/nixos/nixos-config .
sudo chown ユーザ名 -R nixos-config

flake.nixにhome-managerの設定を追記する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  inputs = {
    ...
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = inputs: {
    ...
    homeConfigurations = {
      myHome = inputs.home-manager.lib.homeManagerConfiguration {
        pkgs = import inputs.nixpkgs {
          system = "x86_64-linux";
          config.allowUnfree = true;
        };
        extraSpecialArgs = {
          inherit inputs;
        };
        modules = [
          ./home.nix
        ];
      };
    };
  };
}

home.nixをまず次のようにする。

1
2
3
4
5
6
7
8
{
  home = rec {
    username = "ユーザ名";
    homeDirectory = "/home/${username}";
    stateVersion = "23.11";
  };
  programs.home-manager.enable = true;
}

初回設定の適用

1
nix run home-manager -- switch --flake .#myHome

後はhome.nixを書き換えて好きなパッケージを入れる。