From 6a1caac942fb220906b75499090f5d6b3aeeae4a Mon Sep 17 00:00:00 2001 From: aster <137767097+aster-void@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:48:22 +0900 Subject: [PATCH] wip --- .../docs/utilities/nix/0-references.md | 26 ---- .../docs/utilities/nix/1-get-started.md | 43 ++----- .../utilities/nix/2-ecosystem-nix-shell.md | 33 ++--- src/content/docs/utilities/nix/3-nix-expr.md | 63 +++++----- .../docs/utilities/nix/4-shell-nix.mdx | 69 +++------- src/content/docs/utilities/nix/5-flakes.md | 118 +++++------------- .../docs/utilities/nix/6-home-manager.md | 24 ++-- .../utilities/nix/7-package-definition.md | 56 ++++----- .../docs/utilities/nix/8-after-this.md | 31 +++++ src/content/docs/utilities/nix/9-errors.md | 34 +++-- 10 files changed, 184 insertions(+), 313 deletions(-) delete mode 100644 src/content/docs/utilities/nix/0-references.md create mode 100644 src/content/docs/utilities/nix/8-after-this.md diff --git a/src/content/docs/utilities/nix/0-references.md b/src/content/docs/utilities/nix/0-references.md deleted file mode 100644 index a19f221..0000000 --- a/src/content/docs/utilities/nix/0-references.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: 0. Nix 資料集 ---- - -## チュートリアル系 - -- [Nix 入門: ハンズオン編 - Asahi | Zenn](https://zenn.dev/asa1984/books/nix-hands-on) -- [NixOS & Flake Book](https://nixos-and-flakes.thiscute.world/) - -## データベース系 - -Nixpkgs のパッケージの検索: -[NixOS Search - Packages](https://search.nixos.org/packages) - -NixOS の設定の検索: -[NixOS Search - Options](https://search.nixos.org/options) - -NixOS Wiki (公式): -[NixOS Wiki](https://wiki.nixos.org/wiki/NixOS_Wiki) - -## コミュニティ - -- [Nix 日本語コミュニティ | GitHub (-> Discord)](https://github.com/nix-ja) -- [Nix/NixOS (unofficial) | Discord](https://discord.com/invite/BMUCQx6) - -あとなぜか vim-jp の Slack で Nix が人気という噂 diff --git a/src/content/docs/utilities/nix/1-get-started.md b/src/content/docs/utilities/nix/1-get-started.md index 00bef53..6c30bed 100644 --- a/src/content/docs/utilities/nix/1-get-started.md +++ b/src/content/docs/utilities/nix/1-get-started.md @@ -4,47 +4,27 @@ title: 1. Nix の目的と環境構築 ## そもそも Nix とは? -Nix は、一言でいうと、**ソフトウェアのパッケージ方法を定義する可搬な記述式**です。 +Nix は、ソフトウェアのビルドと実行環境を宣言的に記述し、再現可能に提供するためのツールチェーンです。 ## Nix で何ができる? -Nix (+ flakes) を使うと、以下のようなことの組み合わせが簡単に達成できます。 - -(定義部分) - -- [nixpkgs](https://search.nixos.org) で定義されている大量のパッケージを利用する -- ソフトウェアのビルド式を定義し、**誰でもビルドできる**ようにする - - 依存関係の明示化も Nix に強制されるので、必要な依存が見つからない!が起こり得ない -- 任意の GitHub リポジトリの任意の ref を、 Flake が定義されている限り **手動でクローンせずに** 実行する。 -- 上のすべてを、**コミットハッシュ単位で**バージョンを固定して行う - - かつ、 1 コマンドでアップデート可能 - -(利用部分) - -↑で定義したすべてのソフトウェアを使って、 - -- 開発用シェルの定義を記述し、開発者の間で共有する (`shell.nix`, `devShell`) -- ユーザースペースの定義、その方法の共有 (Home Manager, modules) - - ファイル (`.bashrc`など) や、ソフトウェアのインストールなど -- OS の設定の一元的管理 (NixOS) - - ソフトウェアのインストールなど +- Nixpkgs の大量のパッケージを再現可能に利用できる。 +- 自作ソフトのビルド式を記述し、誰でも同じ方法でビルドできる。 +- Flakes で依存をコミットハッシュにロックし、複数人・複数端末で同じ環境を共有できる。 +- 開発用シェル (`devShell`)・ユーザー設定 (Home Manager)・OS 設定 (NixOS) を一貫した記述で管理できる。 ## 環境構築 ### 1. Nix のインストール -公式のインストーラー - -または、 Determinate Systems のインストーラー -を利用してください。 +- 公式: https://nixos.org/download/ +- Determinate Systems: https://github.com/DeterminateSystems/nix-installer -Determinate Systems のインストーラーは、デフォルトで後述 (2.) の設定が ON になっていたり、アンインストーラーが付属したりしています。 +どちらも現在の Nix をインストールできます。Determinate 版はアンインストーラ付きで、`flakes`/`nix-command` をデフォルトで有効化します。 -チャンネル (後述) を聞かれた場合は、 `nixpkgs-unstable` を選択してください。 +### 2. Nix CLI の設定 (必要な場合) -### 2. Nix CLI の設定 (公式のインストーラー利用時) - -次のコマンドを実行 (するか、同等のことを) してください。 +新 CLI と Flakes を使うために、未設定なら有効化します。 ```sh mkdir -p ~/.config/nix echo 'experimental-features = nix-command flake' > ~/.config/nix/nix.conf @@ -52,8 +32,7 @@ echo 'experimental-features = nix-command flake' > ~/.config/nix/nix.conf ### 3. 確認 -次のコマンドを実行して、 `Hello, Nix!` と表示されたら成功です。 +次のコマンドを実行し、 `Hello, Nix!` と表示されれば成功です。 ```sh nix run nixpkgs#hello -- --greeting 'Hello, Nix!' ``` - diff --git a/src/content/docs/utilities/nix/2-ecosystem-nix-shell.md b/src/content/docs/utilities/nix/2-ecosystem-nix-shell.md index e680bfc..052e761 100644 --- a/src/content/docs/utilities/nix/2-ecosystem-nix-shell.md +++ b/src/content/docs/utilities/nix/2-ecosystem-nix-shell.md @@ -1,17 +1,25 @@ --- -title: 2. エコシステムの全体像と Nix Shell +title: 2. エコシステム概要と Nix Shell 基本 --- ## Nix エコシステムの全体像 -多分分かるので、そのうち書く。 +- Nix: 純粋関数型のビルドシステム兼パッケージマネージャ +- Nixpkgs: 全パッケージ定義集 (公式リポジトリ) + - NixOS: OS 設定を Nix で宣言的に管理する Linux ディストロ。 Nixpkgs に含まれる +- Home Manager: ユーザー環境の宣言的管理 + +### 用語説明 +- Nix Store: `/nix/store` 下の内容アドレス可能なビルド成果物置き場。 +- Channels: 旧来のパッケージ参照方式。 +- Flakes: 入力をロックして再現性を高める新方式。 ## Nix Shell -Nix CLI を使い、Nix Shell を作成してみましょう。 +一時シェルを作ります。 ```sh -nix-shell -p lolcat cowsay +nix-shell -p cowsay lolcat ``` `lolcat` と `cowsay` が利用できるシェルが作成され、そのシェルに入ります。 @@ -23,12 +31,10 @@ which lolcat # -> /nix/store/9qirzkmk1vlj7klw0mjwjkaxpqgh8jdy-lolcat-100.0.1/bin/lolcat ``` -ここで大事なのは、 +ポイント: -- 実行可能ファイルのダウンロードはされている -- グローバルの環境にインストールされているわけではない -- `/nix/store` の中にパッケージのそのバージョン専用のディレクトリが作成されている - - `/nix/store` のことを `Nix Store` と呼ぶことがあります +- プログラムはダウンロードされるが、グローバルには汚さない。 +- `/nix/store` にハッシュ付きパスとして配置される (Nix Store)。 `lolcat` と `cowsay` を使ってみましょう。 @@ -48,14 +54,13 @@ which cowsay # -> which: no cowsay in (path) ``` -## パッケージキャッシュ +## キャッシュとクリーンアップ -Nix Store にパッケージのキャッシュが残っているので、次同じパッケージを使って `nix-shell` をすると、ダウンロードが発生しないのが確認できます。 +Nix Store にキャッシュが残るため、同じパッケージは再ダウンロードされません。 -このキャッシュを消去するには、 +キャッシュのクリーンアップは次のいずれかでできます。 ```sh +nix store gc nix-collect-garbage ``` - -を実行します。 diff --git a/src/content/docs/utilities/nix/3-nix-expr.md b/src/content/docs/utilities/nix/3-nix-expr.md index 85f1e73..394c68a 100644 --- a/src/content/docs/utilities/nix/3-nix-expr.md +++ b/src/content/docs/utilities/nix/3-nix-expr.md @@ -30,17 +30,18 @@ Nix 式は、多くの関数型言語と同じように、遅延評価されま ``` ```nix 2 * 3 -# -> 3 +# -> 6 ``` 文字列 ```nix +# JavaScript と違い、 `'` 単体で文字列を囲むことはできない "hello, " + "nix" # -> "hello, nix" ``` ```nix -# 複数行使う場合は '' を使う +# 複数行使う場合は `''` でかこむ '' multi-line string @@ -56,6 +57,7 @@ string ``` ```nix +# 結合 [ 1 2 ] ++ [ 3 4 ] # -> [ 1 2 3 4] ``` @@ -74,7 +76,7 @@ true ## `let ... in` 構文 -いわゆる「変数」を定義できます。なお、Nix は関数型言語なので、変数の変更はできません。 +式に名前をつけることができます。なお、Nix は関数型言語なので、名前のついた式の変更はできません。 ```nix let @@ -87,10 +89,10 @@ in a + 2; ```nix let - b = a + 2; + b = a + 2; # 先の式も参照できる a = 3; in a + b -# -> 8 +# -> 8 (3 + 2 + 3) ``` ## Attrset @@ -105,7 +107,7 @@ in a + b # -> { a = 1; b = 2; } ``` -もちろん、アトリビュート (プロパティ) にアクセスすることもできます。 +attribute (プロパティ) には、 `.` でアクセスすることができます。 ```nix let @@ -118,6 +120,19 @@ in # -> 2 ``` +アクセスする変数を評価時に決めたい場合は、 Interpolation `${}` を使います。 + +```nix +let + attrs = { + a = 1; + b = 2; + } + key = "b"; +in + attrs.${key} # -> 2 +``` + `rec` キーワードを使うと、自身のメンバーにアクセスできます。 ```nix @@ -130,6 +145,8 @@ rec { ## 関数 +Nix で関数は、`引数: 返り値` という形で作ります。 + ```nix # 引数をひとつとる関数 let @@ -147,7 +164,7 @@ toString 2 # -> "2" ``` -よくある関数言語のように、Nix の関数は引数を一つしかとれないので、複数の引数をとる関数を定義する場合は、Attrset を使うか「カリー化」をします。 +Nix の関数は引数を一つしかとれないので、複数の引数をとる関数を定義する場合は、Attrset を使うか、複数回呼び出すようにします。 ```nix # attrset をとる例 @@ -160,41 +177,22 @@ in ``` ```nix -# カリー化する例 +# 複数回呼び出す関数 (カリー化と言ったり言わなかったりする) let - # カリー化された関数: 返り値をもう一度呼び出して解を得る + # 返り値をもう一度呼び出して解を得る add = a: b: a + b; in add 2 3 # -> 5 ``` +`map` のような高階関数もたくさんあります。 -:::tip[カリー化とは?] - -文字で読むより上の例を見たほうが分かりやすいと思います。 -上の例を読んで理解したら、この Tip は読まなくてもいいです。 - -カリー化とは、わかりやすく言うと、呼び出したときに、その引数を保存した新しい関数を返すことです。 - -TypeScript で例えるとこのようになります。 - -```ts -function add(a: number) { - return (b: number) => a + b; -} - -console.log(add(2)(3)); // -> 5 - -// 部分的に適用することもできる -const curried = add(4); -console.log(curried(5)); // -> 9 +```nix +builtins.map (x: x * 2) [1 2 3] +# -> [ 2 4 6 ] ``` -正確な定義は [Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96) を参照してください。 - -::: - ## パス Nix では、パスも基本型の一つです。 @@ -205,4 +203,3 @@ Nix では、パスも基本型の一つです。 builtins.readFile ./path.txt # -> "hello path\n" ``` - diff --git a/src/content/docs/utilities/nix/4-shell-nix.mdx b/src/content/docs/utilities/nix/4-shell-nix.mdx index 3bf08c5..603a3e4 100644 --- a/src/content/docs/utilities/nix/4-shell-nix.mdx +++ b/src/content/docs/utilities/nix/4-shell-nix.mdx @@ -20,9 +20,7 @@ title: 4. Nix ファイルで Nix Shell を定義し、自動で読み込む ## シェル定義ファイル -### 動かしてみる - -まずはシェル定義ファイルを作成し、動かしてみましょう。詳しい構文は後で説明します。 +まずは最小の定義を作って動かします。 ```nix title="shell.nix" let @@ -38,7 +36,9 @@ in ``` ```sh -nix-shell ./shell.nix # ファイル名が与えられないとデフォルトで `shell.nix` を使うので、省略も可能 +nix-shell ./shell.nix # 旧 CLI +# または (Flake) +# nix develop # flake.nix がある場合 hello --greeting 'Hello, Nix!' # -> Hello, Nix! @@ -50,49 +50,10 @@ hello --greeting 'Hello, Nix!' # -> hello: command not found ``` -### 構文の説明 - -#### `import {}` - -主に `pkgs` という変数名にされる、 [Nixpkgs](https://github.com/NixOS/nixpkgs) のライブラリをすべて格納した Attrset に評価されます。これのことを Nixpkgs と呼ぶこともあります。 - -ここに大量のプログラムと Nix の公式ライブラリ関数がすべて格納されています。 - -本当はこれ以上分解できるのですが、難しいのでこの単位で捉えても構いません。 -一年くらい Nix してるとそのうちわかるかもしれませんね。 - -
- 詳しい説明 - - `import`: パスを引数に取り、その場所にある Nix ファイルの中身に展開される builtin 関数。 - - `{}`: 空の Attrset。 `import ` はオプションを取って `pkgs` を返す関数になるので、すべてのオプションをデフォルトで呼び出す。 - - --- - - `` をさらに分解する - - `<>` 構文: 間に挟まれた文字列に対応する Nix Path を、`$NIX_PATH` 環境変数などから探してくる構文。 - - `$NIX_PATH` は `key=URL` やチャンネル (たぶん後述) のパスを `:` で接続した形式になっている。 URL のスキームの区切り (例: `http:...`, `file:...`) にも `:` が使われるので、非常に紛らわしい。 +### ポイント - ```sh title=bash - echo $NIX_PATH - # -> nixpkgs=flake:nixpkgs:/nix/var/nix/profiles/per-user/root/channels - # nixpkgs=flake:nixpkgs と /nix/var/nix/profiles/per-user/root/channels に分解できる。 - ``` - - 今回の場合は `nixpkgs=flake:nixpkgs` にマッチするので、どうなるんだろう? - - 最終的には、 `` は `/nix/store/(hash)-source` というパスになる。このパスの中身は、 `nixpkgs` のリポジトリのようだ。 -
- -#### `pkgs.mkShell {...}` - -Nixpkgs のライブラリ関数の一つで、シェルを表現する Attrset (Derivation と呼ばれる、たぶん後述) を返します。 - -引数の Attrset のとるオプションには、以下が含まれます: - -- `packages`: シェルで使用可能にするパッケージのリスト。 -- `env`: 環境変数を表す Attrset。 +- `import {}` は Nixpkgs のパッケージ集合 (`pkgs`) を読み込みます。 +- `pkgs.mkShell { packages = [...] ; }` で必要ツールを含むシェルを作れます。 ## Direnv を使って自動で Nix Shell に入る @@ -104,15 +65,19 @@ Home-Manager や NixOS を使う予定の方は、先にそれらのセットア Home-Manager も NixOS も使う予定のない方は、このまま進んでください。 ::: -1. Direnv をインストールします。 [https://direnv.net/docs/installation.html](https://direnv.net/docs/installation.html) - - Home Manager か NixOS のある方はそれでインストールしてください。 -2. Nix-Direnv をインストールします。 [https://github.com/nix-community/nix-direnv](https://github.com/nix-community/nix-direnv) - - Home Manager か NixOS のある方はそれを、ない方は「Install with `nix profile`」を選択してください。 +1. Direnv をインストール: https://direnv.net/docs/installation.html +2. Nix-Direnv をセットアップ: https://github.com/nix-community/nix-direnv ### 自動で Nix シェルを読み込む -Direnv は、 `.envrc` ファイルを使って設定します。まずは、 `.envrc` を作成しましょう。 +Direnv は `.envrc` で設定します。 + +Flake あり: +```txt title=".envrc" +use flake +``` +Flake なし: ```txt title=".envrc" use nix ``` @@ -123,7 +88,7 @@ Direnv に `direnv: error .envrc is blocked. Run direnv allow to approve its con direnv allow ``` -これで、そのディレクトリに入ったときに自動で Nix シェルが起動するようになりました。 +これでディレクトリ入場時に自動で Nix シェルが起動します。 試しに、1個上のディレクトリと行き来してみましょう。 diff --git a/src/content/docs/utilities/nix/5-flakes.md b/src/content/docs/utilities/nix/5-flakes.md index 3be8b24..a013b31 100644 --- a/src/content/docs/utilities/nix/5-flakes.md +++ b/src/content/docs/utilities/nix/5-flakes.md @@ -4,130 +4,72 @@ title: 5. Nix Channel と Flake # Nix のバージョン固定方法 -Nix には、バージョン固定システムが *Nix Channel* (古い) と *Nix Flake* (新しい) の2つあります。 +Nix の参照方法は大きく「Channels (旧来)」と「Flakes (現行)」の二系統があります。新規プロジェクトは Flakes を推奨します。 -## Nix Channel +## Nix Channels (レガシー) -Nix Channel は、コンピュータごとに管理される、バージョン固定システムです。 +`nix-env`/`nix-shell` のような古い CLI で解決に使われる旧来の参照方式です。マシン単位で管理・更新します。 ```sh -nix-channel --list -# -> nixpkgs https://nixos.org/channels/nixpkgs-unstable +nix-channel --list # 一覧 +nix-channel --update # アップデート ``` -Nix をインストールしたときは、デフォルトで Nix Channel を使っているはずです (要検証)。 +## Nix Flakes (推奨) -Nix Channel には `nixpkgs-unstable`, `nixos-unstable`, `nixos-24.11` などと名前がおり、それぞれが Nixpkgs のリポジトリの特定の条件を満たした (特定の CI が通るなど) コミットのうち最新のものを指しています。 +Flake とは、 `flake.nix` と `flake.lock` を含む **Git リポジトリ** のことを指します。リポジトリに `flake.nix` (定義) と `flake.lock` (入力を固定) を置いて再現性を担保します。 -### Nix Channel のアップデート +`flake.nix` は、少なくとも以下のプロパティを持つ必要があります: -チャンネルの保存するコミットは明示的に更新しない限りアップデートされません。 - -最新のものにアップデートするには、次のコマンドを実行してください。 - -```sh -nix-channel --update -``` - -(TODO: チャンネルはどう使われる?推測するに、 NIX_PATH の解決時に使われるただのキャッシュなのではないか。) - -## Nix Flake - -Nix Flake は、新しい Nix のバージョン管理の方法です。Git に依存します。 - -リポジトリに `flake.nix` という Flake の定義ファイルと、 `flake.lock` というバージョン固定ファイルを置いてバージョンを管理します。 -### Flake を使ってみる - -まずは、 Flake を作成します。 +- `inputs`: Flake の依存する「可変入力」を表す attrset。 `nixpkgs` やサードパーティ Flake が該当する。 +- `outputs`: Flake の表現するもの。任意の値を持つことができるが、とくに `devShells` は `nix develop` 用のもので、 `` +作成: ```sh nix flake init +nix flake init -t <テンプレート> ``` -すると、次のような `flake.nix` と `flake.lock` が生成されます。 `flake.lock` の方は手動で編集することはありません。 - +最小の `devShell` 例: ```nix { - description = "A very basic flake"; - inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - }; - - outputs = { self, nixpkgs }: { - - packages.x86_64-linux.hello = nixpkgs.legacyPackages.x86_64-linux.hello; - - packages.x86_64-linux.default = self.packages.x86_64-linux.hello; - - }; -} -``` - -description は人間向けの Flake の説明です。 - -`inputs` は、Flake の「入力」を表します。Flake の時間依存性を示し、Flake はこれを特定の瞬間に固定することでバージョンを固定します。 - -`outputs` が Flake のメイン部分です。引数には上で定義した `inputs` と自分自身を表す `self` を合体した Attrset が渡され、返り値は自由な Attrset です。 - -`outputs` の返り値のキーは自由に指定でき、例えば `packages.${system}` を指定すると `nix run` コマンドで直接実行できるようになり、 `checks.${system}` を指定すると `nix check` でテストを実行できます ([参考](https://zenn.dev/ttak0422/articles/4ee6b3750a7b70))。 - -今回は、前の章で書いた `shell.nix` を Flake に変換してみましょう。 - -生成された `flake.nix` を以下のように書き換えます。 - -```nix - -{ - description = "A very basic flake"; - - inputs = { - nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + nixpkgs.url = "github:nixos/nixpkgs?ref=nixpkgs-unstable"; }; outputs = { self, nixpkgs }: let - system = "x86_64-linux"; + system = "x86_64-linux"; # 端末のシステムに合わせる pkgs = nixpkgs.legacyPackages.${system}; in { devShells.${system}.default = pkgs.mkShell { - packages = [pkgs.hello pkgs.cowsay pkgs.lolcat]; + packages = with pkgs; [ hello cowsay lolcat ]; }; }; } ``` -(todo: git add することを書く) -(todo: system はお使いの端末のシステムに揃えることを書く) -(todo: `${}` 構文の説明をする) -(todo: 各システム分書くのは面倒なので、ふつうは `flake-utils` や `flake-parts` などのライブラリを使うことを書く (手書きしてもいいが...)) -(todo: pkgs.mkShell {} 以下が見慣れた shell.nix であることを書く) -(todo: legacyPackges がなぜ legacy なのか書く (そんな重要な意味はない)) - -### Flake のバージョンアップ - -(todo: 適当なこと書く) +使い方: ```sh -nix flake update +nix develop .#default # devShells.${system}.defaultに入る +nix run .#hello # apps.${system}.hello / packages.${system}.hello を実行する ``` -### Nix Flake のメリット・デメリット +### Flake のバージョン管理 -Flake は、ユーザーごとのバージョン解決方法ではなくロックファイルからバージョンを解決するので、以下のようなメリット・デメリットがあります。 +- 依存を一括更新: `nix flake update` +- 特定入力だけ更新: `nix flake lock --update-input nixpkgs` -メリット - -- 複数人や複数のマシンで使うとき、正確な依存関係を共有できる -- そのディレクトリで明示的に更新しないと更新されないため、バージョンアップ時の動作確認が容易 -- サードパーティーのライブラリを簡単にインストールできる +### Flakes の特徴 -デメリット +メリット +- 依存をロックし、複数人・複数端末で同一環境を再現できる。 +- 更新は明示的に行い、変更点をレビュー可能。 +- `inputs` に外部 Flake を指定して容易に拡張可能。 -- ロックファイルで指定されたバージョンをそれぞれインストールするため、あまりにも大量の Flake を使おうとするとディスクの容量を食う -- 定期的にロックファイルをアップデートしないとパッケージが古くなってしまう +注意点 +- ロック単位で依存が増えるため、Flake 数が多いとストア使用量が増える。 +- ロック更新を継続的に行わないと古くなる。 ### 演習 -演習として、 [Bunnix](https;//github.com/aster-void/bunnix) という Nix で Bun をバージョン管理するためのライブラリを Flake にインストールしてみましょう。 - -シェルに入ったら、 Bun のバージョン 1.1.39 (最も偉大なバージョン) が使えるようにしてみましょう。 diff --git a/src/content/docs/utilities/nix/6-home-manager.md b/src/content/docs/utilities/nix/6-home-manager.md index ece20fb..a4d994a 100644 --- a/src/content/docs/utilities/nix/6-home-manager.md +++ b/src/content/docs/utilities/nix/6-home-manager.md @@ -4,19 +4,18 @@ title: 6. Home Manager を使う 参照: [Home Manager Manual](https://nix-community.github.io/home-manager/) -todo: 誰か動作確認して - -## Home Manager をセットアップする +## セットアップ (単独利用) +リリースブランチを指定して初期化します (例: 24.11)。 ```sh -nix run home-manager/master -- init --switch +nix run home-manager/release-24.11 -- init --switch ``` -`~/.config/home-manager` に Home Manager のモジュールが生成されます。`` +`~/.config/home-manager` に設定が生成されます。 ## パッケージをインストールする -`~/.config/home-manager/home.nix` に、以下の行を追加してください。 +`~/.config/home-manager/home.nix` に追加します。 ```nix { @@ -32,11 +31,12 @@ nix run home-manager/master -- init --switch } ``` +反映: ```sh home-manager switch ``` -Home Manager がビルドを実行したあと、Nix 経由で Bun がインストールされます。 +Home Manager のビルド後、Nix 経由で Bun が利用可能になります。 ```sh which bun @@ -45,9 +45,7 @@ which bun ## モジュールを分割する -Home Manager の設定ファイルが成長してくると、 `home.nix` だけでは大きくなりすぎてしまいます。 - -複数ファイルに分割してみましょう。 +設定が大きくなったらファイルを分割して `imports` します。 ```nix title="home.nix" { @@ -71,8 +69,6 @@ Home Manager の設定ファイルが成長してくると、 `home.nix` だけ } ``` -`imports` にインポートしたいモジュールを指定すると、モジュールがインポートされます。`` - -## カスタムモジュールを定義する +`imports` にインポートしたいモジュールを列挙します。 -HELP NEEDED: どうやってやるのこれ +フレーク管理に移行する場合は、`~/.config/home-manager/flake.nix` を作成し、`homeConfigurations.${username}` を定義して `home-manager switch` を実行します。 diff --git a/src/content/docs/utilities/nix/7-package-definition.md b/src/content/docs/utilities/nix/7-package-definition.md index afac5fe..605b4f6 100644 --- a/src/content/docs/utilities/nix/7-package-definition.md +++ b/src/content/docs/utilities/nix/7-package-definition.md @@ -2,13 +2,11 @@ title: 7. Nix でパッケージを定義する --- -Nix のパッケージを表すものとして、derivation というものがあります。 - -(めんどくなったので、あとは勝手に調べてください。) +Nix ではビルド単位を derivation と呼びます。ここでは最小のパッケージ定義を作って動かします。 ## パッケージを記述する -`stdenv.mkDerivation` というラッパーを使い、パッケージを記述しましょう。 +`stdenv.mkDerivation` を使って定義します。 ```go title="main.go" package main @@ -21,24 +19,21 @@ func main() { ``` ```nix -{pkgs ? import {}}: let - pname = "hello-nix"; -in - pkgs.stdenv.mkDerivation { - inherit pname; - version = "0.0.0"; - src = ./.; - buildInputs = [pkgs.go]; - buildPhase = '' - # キャッシュのディレクトリを設定する (気にしなくて良い) - export GOCACHE=/tmp/gocache - go build ./main.go - ''; - installPhase = '' - mkdir -p $out/bin - mv ./main $out/bin/${pname} - ''; - } +{ pkgs ? import {} }: +let pname = "hello-nix"; +in pkgs.stdenv.mkDerivation { + inherit pname; + version = "0.0.0"; + src = ./.; + buildInputs = [ pkgs.go ]; + buildPhase = '' + export GOCACHE=$TMPDIR/gocache + go build -o ${pname} ./main.go + ''; + installPhase = '' + install -Dm755 ${pname} $out/bin/${pname} + ''; +} ``` ビルドしてみましょう。 @@ -56,8 +51,7 @@ nix-build ./package.nix ## インストールしてみる -今回は Nix シェルにインストールしますが、Home Manager や NixOS にも同様の手順でインストールできます。 -`pkgs.callPackage` は、他のファイルに記述した Nix 関数を呼び出すのに使えます。 +今回は Nix シェルに取り込みます。`pkgs.callPackage` でローカル定義を呼び出せます。 ```nix title="shell.nix" {pkgs ? import {}}: let @@ -79,8 +73,7 @@ hello-nix # `$out/bin` の中に作成したバイナリのファイル名で呼 ## Flake にする -このままだと、 `package.nix` とそのソースがローカルに存在しないと使えません。あまり便利ではないですね。 -Flake にして、 GitHub で全世界に配布してみましょう。 +Flake 化するとどこからでも参照できます。 ```nix title="flake.nix" { @@ -104,15 +97,10 @@ Flake にして、 GitHub で全世界に配布してみましょう。 } ``` -これをコミットして、 リポジトリのルートにおいて GitHub の公開リポジトリにアップロードします。 - -すると、任意の場所 (あなたのパソコンである必要もありません) から Flake を呼び出せるようになります。 - +コミット・公開後は次のように実行できます。 ```sh -nix run github:$USER/$REPO # default を実行 +nix run github:$USER/$REPO # default を実行 nix run github:$USER/$REPO#hello-nix # hello-nix を実行 ``` -ちなみに、この教材のリポジトリにも `hello-nix` をおいてあるので、 `nix run github:ut-code/extralearn` で hello-nix が実行できます。 - -Cachix とかで、ビルド結果を共有キャッシュにすることもできるらしいです。(やったことない) +共有キャッシュ (例: Cachix) を用意すればビルド時間を短縮できます。 diff --git a/src/content/docs/utilities/nix/8-after-this.md b/src/content/docs/utilities/nix/8-after-this.md new file mode 100644 index 0000000..9d7a671 --- /dev/null +++ b/src/content/docs/utilities/nix/8-after-this.md @@ -0,0 +1,31 @@ +--- +title: 8. 今後の学習パス +--- + +## 教材 + +てかこんなよくわからないの読んでないでこれ読め +- [Nix 入門: ハンズオン編 - Asahi | Zenn](https://zenn.dev/asa1984/books/nix-hands-on) + +## 開発ツール + +- Nix Direnv (`cd` したときに自動で devshell に入る) + +## Flake ユーティリティ + +- `flake-utils` 便利。 +- `blueprint` 便利。 + +## Nixpkgs の検索 + +- NixOS Search + - パッケージのみ +- Noogle + - `pkgs.lib` の検索 + +## NixOS + +- NixOS Search + +NixOS Wiki (公式): +[NixOS Wiki](https://wiki.nixos.org/wiki/NixOS_Wiki) diff --git a/src/content/docs/utilities/nix/9-errors.md b/src/content/docs/utilities/nix/9-errors.md index 3793582..8a6a7e3 100644 --- a/src/content/docs/utilities/nix/9-errors.md +++ b/src/content/docs/utilities/nix/9-errors.md @@ -2,31 +2,25 @@ title: 9. Nix/NixOS でよくあるミス・引っかかりやすいところ --- -### Flake が認識されない / Flake で Nix ファイルが見つからないと出る +### Flake がファイルを見つけない -`git add` する。終わり。 +Flake は Git に追跡されるファイルのみをソースとして取り込みます。新規ファイルは `git add` してから評価してください。 -詳しい説明は、以下の通り。 +理由: Flake は純粋性のためにワーキングツリーのうち追跡対象のみを Nix Store にコピーして評価します。 -- Flake は、純粋性の確保のため、いったんリポジトリを Nix Store にコピーしてから評価するという挙動をとる。 -- このとき、git を使ってコピーしてるっぽい?。 git に認知されているファイルはステージされていなくても問題なくコピーできるが、 git が認知していない (untracked) ファイルはコピーできない。 -- コピーできないため、ファイルが見つからないと表示される。 +### NixOS で一部の Node/NPM ツールが動かない -### NixOS で NPM ライブラリ XXX が動かない +配布バイナリをダウンロードして実行するツールは、NixOS のリンカ/ライブラリと合わず動かない場合があります。 -たいていの場合はそのライブラリがバイナリを引っ張ってくる野蛮なライブラリだから。 (ex. wrangler, sharp, prisma, ...) +対策: +- 可能なら Nixpkgs 版を使う。 +- `nix-ld` を導入して実行時リンカを補助する。 +- それでも不可なら各ツールの推奨手順に従って環境変数でバイナリを指定する (例: Prisma)。 -nix-ld を入れればたいていは解決。 +### Flake で fetcher がエラーになる -- Prisma の場合は、バイナリの引っ張り方が無駄に丁寧 (distribution で switch してる) ので、環境変数でバイナリを指定してやる。 [nix-prisma-utils](https://github.com/VanCoding/nix-prisma-utils) が便利。 -- Wrangler の場合は、 nix-ld を入れてる自分の環境でも動かなそうなので、 Nixpkgs からインストールしよう。 -- その他自分の把握してないライブラリは [ここ](https://zenn.dev/asa1984/scraps/17fe60c1b2ccc2) 参照。 +Flake は純粋性のためネットワーク取得にハッシュを要求します。 -### Flake で fetcher を使うとエラー - -Flake の純粋性を保つため。 - -選択肢は2つあり、 - -- `inputs` を使う (おすすめ) -- fetcher にハッシュを渡す (どうしようもない時) +回避: +- 外部ソースは `inputs` に定義して参照する (推奨)。 +- fetcher を使う場合は `sha256` などの固定ハッシュを明示する。