mirror of
https://github.com/ryan4yin/nixos-and-flakes-book.git
synced 2024-11-22 16:13:26 +01:00
feat: finish 'best practices'
This commit is contained in:
parent
9db31c0d59
commit
02cb15d169
@ -83,6 +83,24 @@ export default defineConfig({
|
|||||||
{ text: "Overlays", link: "/nixpkgs/overlays.md" },
|
{ text: "Overlays", link: "/nixpkgs/overlays.md" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: "Best Practices",
|
||||||
|
items: [
|
||||||
|
{ text: "Introduction", link: "/best-practices/intro.md" },
|
||||||
|
{
|
||||||
|
text: "Run downloaded binaries on NixOS",
|
||||||
|
link: "/best-practices/run-downloaded-binaries-on-nixos.md",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Simplify NixOS-related Commands",
|
||||||
|
link: "/best-practices/simplify-nixos-related-commands.md",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Debug with nix repl",
|
||||||
|
link: "/best-practices/debug-with-nix-repl.md",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
@ -178,7 +196,21 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "NixOS 最佳实践",
|
text: "NixOS 最佳实践",
|
||||||
items: [{ text: "快速入门", link: "/zh/best-practices/index.md" }],
|
items: [
|
||||||
|
{ text: "简介", link: "/zh/best-practices/intro.md" },
|
||||||
|
{
|
||||||
|
text: "运行非 NixOS 的二进制文件",
|
||||||
|
link: "/zh/best-practices/run-downloaded-binaries-on-nixos.md",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "使用 Makefile 简化常用命令",
|
||||||
|
link: "/zh/best-practices/simplify-nixos-related-commands.md",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "使用 nix repl 查看源码、调试配置",
|
||||||
|
link: "/zh/best-practices/debug-with-nix-repl.md",
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "Flakes 的其他玩法",
|
text: "Flakes 的其他玩法",
|
||||||
|
152
docs/best-practices/debug-with-nix-repl.md
Normal file
152
docs/best-practices/debug-with-nix-repl.md
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
|
||||||
|
## Debug with `nix repl`
|
||||||
|
|
||||||
|
We've used `nix repl '<nixpkgs>'` many times to check the source code in this guide, it's really a powerful tool to help us understand how things work in Nix.
|
||||||
|
|
||||||
|
Better take a look at the help message of `nix repl`:
|
||||||
|
|
||||||
|
```
|
||||||
|
› nix repl -f '<nixpkgs>'
|
||||||
|
Welcome to Nix 2.13.3. Type :? for help.
|
||||||
|
|
||||||
|
Loading installable ''...
|
||||||
|
Added 17755 variables.
|
||||||
|
nix-repl> :?
|
||||||
|
The following commands are available:
|
||||||
|
|
||||||
|
<expr> Evaluate and print expression
|
||||||
|
<x> = <expr> Bind expression to variable
|
||||||
|
:a <expr> Add attributes from resulting set to scope
|
||||||
|
:b <expr> Build a derivation
|
||||||
|
:bl <expr> Build a derivation, creating GC roots in the working directory
|
||||||
|
:e <expr> Open package or function in $EDITOR
|
||||||
|
:i <expr> Build derivation, then install result into current profile
|
||||||
|
:l <path> Load Nix expression and add it to scope
|
||||||
|
:lf <ref> Load Nix flake and add it to scope
|
||||||
|
:p <expr> Evaluate and print expression recursively
|
||||||
|
:q Exit nix-repl
|
||||||
|
:r Reload all files
|
||||||
|
:sh <expr> Build dependencies of derivation, then start nix-shell
|
||||||
|
:t <expr> Describe result of evaluation
|
||||||
|
:u <expr> Build derivation, then start nix-shell
|
||||||
|
:doc <expr> Show documentation of a builtin function
|
||||||
|
:log <expr> Show logs for a derivation
|
||||||
|
:te [bool] Enable, disable or toggle showing traces for errors
|
||||||
|
```
|
||||||
|
|
||||||
|
Some expressions that I use frequently: `:lf <ref>`, `:e <expr>`.
|
||||||
|
|
||||||
|
`:e <expr>` is very intuitive, so I won't repeat it. let's take a look at `:lf <ref>`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# cd into my nix-config repo(you should replace it with your own nix-config repo)
|
||||||
|
› cd ~/nix-config/
|
||||||
|
|
||||||
|
# enter nix repl
|
||||||
|
› nix repl
|
||||||
|
Welcome to Nix 2.13.3. Type :? for help.
|
||||||
|
|
||||||
|
# load my nix flake and add it to scope
|
||||||
|
nix-repl> :lf .
|
||||||
|
Added 16 variables.
|
||||||
|
|
||||||
|
# press <TAB> to see what we have in scope
|
||||||
|
nix-repl><TAB>
|
||||||
|
# ......omit some outputs
|
||||||
|
__isInt nixosConfigurations
|
||||||
|
__isList null
|
||||||
|
__isPath outPath
|
||||||
|
__isString outputs
|
||||||
|
__langVersion packages
|
||||||
|
# ......omit some outputs
|
||||||
|
|
||||||
|
|
||||||
|
# check what's in inputs
|
||||||
|
nix-repl> inputs.<TAB>
|
||||||
|
inputs.agenix inputs.nixpkgs
|
||||||
|
inputs.darwin inputs.nixpkgs-darwin
|
||||||
|
inputs.home-manager inputs.nixpkgs-unstable
|
||||||
|
inputs.hyprland inputs.nixpkgs-wayland
|
||||||
|
inputs.nil
|
||||||
|
inputs.nixos-generators
|
||||||
|
|
||||||
|
# check what's in inputs.nil
|
||||||
|
nix-repl> inputs.nil.packages.
|
||||||
|
inputs.nil.packages.aarch64-darwin
|
||||||
|
inputs.nil.packages.aarch64-linux
|
||||||
|
inputs.nil.packages.x86_64-darwin
|
||||||
|
inputs.nil.packages.x86_64-linux
|
||||||
|
|
||||||
|
# check the outputs of my nix flake
|
||||||
|
nix-repl> outputs.nixosConfigurations.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai
|
||||||
|
outputs.nixosConfigurations.aquamarine
|
||||||
|
outputs.nixosConfigurations.kana
|
||||||
|
outputs.nixosConfigurations.ruby
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai._module
|
||||||
|
outputs.nixosConfigurations.ai._type
|
||||||
|
outputs.nixosConfigurations.ai.class
|
||||||
|
outputs.nixosConfigurations.ai.config
|
||||||
|
outputs.nixosConfigurations.ai.extendModules
|
||||||
|
outputs.nixosConfigurations.ai.extraArgs
|
||||||
|
outputs.nixosConfigurations.ai.options
|
||||||
|
outputs.nixosConfigurations.ai.pkgs
|
||||||
|
outputs.nixosConfigurations.ai.type
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.
|
||||||
|
outputs.nixosConfigurations.ai.config.age
|
||||||
|
outputs.nixosConfigurations.ai.config.appstream
|
||||||
|
outputs.nixosConfigurations.ai.config.assertions
|
||||||
|
outputs.nixosConfigurations.ai.config.boot
|
||||||
|
outputs.nixosConfigurations.ai.config.console
|
||||||
|
outputs.nixosConfigurations.ai.config.containers
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activation
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activationPackage
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.emptyActivationPath
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableDebugInfo
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableNixpkgsReleaseCheck
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraActivationPath
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraBuilderCommands
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraOutputsToInstall
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraProfileCommands
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.BROWSER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.DELTA_PAGER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.EDITOR
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.GLFW_IM_MODULE
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.MANPAGER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.QT_IM_MODULE
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
# check the value of `TERM`
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
||||||
|
"xterm-256color"
|
||||||
|
|
||||||
|
|
||||||
|
# check all files defined by `home.file`
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bash_profile
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bashrc
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile-bak
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/config
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/i3blocks.conf
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/keybindings
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/layouts
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/scripts
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/wallpaper.png
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/rofi
|
||||||
|
#......
|
||||||
|
```
|
||||||
|
|
||||||
|
As you can see, we can check every attribute of my flake in the REPL after loading it, which is very convenient for debugging.
|
@ -1,351 +0,0 @@
|
|||||||
|
|
||||||
Nix is powerful and flexible, it provides a lot of ways to do things, making it difficult to find the most suitable way to do your job.
|
|
||||||
Here are some best practices that I've learned from the community, hope it can help you.
|
|
||||||
|
|
||||||
## 1. Run downloaded binaries on NixOS
|
|
||||||
|
|
||||||
NixOS does not follow the FHS standard, so the binaries you download from the Internet will not likely work on NixOS. But there are some ways to make it work.
|
|
||||||
|
|
||||||
Here is a detailed guide which provides 10 ways to run downloaded binaries on NixOS: [Different methods to run a non-nixos executable on Nixos](https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos), I recommend you to read it.
|
|
||||||
|
|
||||||
Among these methods, I prefer creating a FHS environment to run the binary, which is very convenient and easy to use.
|
|
||||||
|
|
||||||
To create such an environment, add the following code to one of your nix modules:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# ......omit many configurations
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# ......omit many packages
|
|
||||||
|
|
||||||
# create a fhs environment by command `fhs`, so we can run non-nixos packages in nixos!
|
|
||||||
(pkgs.buildFHSUserEnv (base // {
|
|
||||||
name = "fhs";
|
|
||||||
targetPkgs = pkgs: (
|
|
||||||
# pkgs.buildFHSUserEnv provides only a minimal fhs environment,
|
|
||||||
# it lacks many basic packages needed by most softwares.
|
|
||||||
# so we need to add them manually.
|
|
||||||
#
|
|
||||||
# pkgs.appimageTools provides basic packages needed by most softwares.
|
|
||||||
(pkgs.appimageTools.defaultFhsEnvArgs.targetPkgs pkgs) ++ with pkgs; [
|
|
||||||
pkg-config
|
|
||||||
ncurses
|
|
||||||
# feel free to add more packages here, if you need
|
|
||||||
]
|
|
||||||
);
|
|
||||||
profile = "export FHS=1";
|
|
||||||
runScript = "bash";
|
|
||||||
extraOutputsToInstall = ["dev"];
|
|
||||||
}))
|
|
||||||
];
|
|
||||||
|
|
||||||
# ......omit many configurations
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
after applying the updated configuration, you can run `fhs` to enter the FHS environment, and then run the binary you downloaded, e.g.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Activating FHS drops me in a shell which looks like a "normal" Linux
|
|
||||||
$ fhs
|
|
||||||
# check what we have in /usr/bin
|
|
||||||
(fhs) $ ls /usr/bin
|
|
||||||
# try to run a non-nixos binary downloaded from the Internet
|
|
||||||
(fhs) $ ./bin/code
|
|
||||||
```
|
|
||||||
|
|
||||||
## 2. check the source code and debug with `nix repl`
|
|
||||||
|
|
||||||
We've used `nix repl '<nixpkgs>'` many times to check the source code in this guide, it's really a powerful tool to help us understand how things work in Nix.
|
|
||||||
|
|
||||||
Better take a look at the help message of `nix repl`:
|
|
||||||
|
|
||||||
```
|
|
||||||
› nix repl -f '<nixpkgs>'
|
|
||||||
Welcome to Nix 2.13.3. Type :? for help.
|
|
||||||
|
|
||||||
Loading installable ''...
|
|
||||||
Added 17755 variables.
|
|
||||||
nix-repl> :?
|
|
||||||
The following commands are available:
|
|
||||||
|
|
||||||
<expr> Evaluate and print expression
|
|
||||||
<x> = <expr> Bind expression to variable
|
|
||||||
:a <expr> Add attributes from resulting set to scope
|
|
||||||
:b <expr> Build a derivation
|
|
||||||
:bl <expr> Build a derivation, creating GC roots in the working directory
|
|
||||||
:e <expr> Open package or function in $EDITOR
|
|
||||||
:i <expr> Build derivation, then install result into current profile
|
|
||||||
:l <path> Load Nix expression and add it to scope
|
|
||||||
:lf <ref> Load Nix flake and add it to scope
|
|
||||||
:p <expr> Evaluate and print expression recursively
|
|
||||||
:q Exit nix-repl
|
|
||||||
:r Reload all files
|
|
||||||
:sh <expr> Build dependencies of derivation, then start nix-shell
|
|
||||||
:t <expr> Describe result of evaluation
|
|
||||||
:u <expr> Build derivation, then start nix-shell
|
|
||||||
:doc <expr> Show documentation of a builtin function
|
|
||||||
:log <expr> Show logs for a derivation
|
|
||||||
:te [bool] Enable, disable or toggle showing traces for errors
|
|
||||||
```
|
|
||||||
|
|
||||||
Some expressions that I use frequently: `:lf <ref>`, `:e <expr>`.
|
|
||||||
|
|
||||||
`:e <expr>` is very intuitive, so I won't repeat it. let's take a look at `:lf <ref>`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# cd into my nix-config repo(you should replace it with your own nix-config repo)
|
|
||||||
› cd ~/nix-config/
|
|
||||||
|
|
||||||
# enter nix repl
|
|
||||||
› nix repl
|
|
||||||
Welcome to Nix 2.13.3. Type :? for help.
|
|
||||||
|
|
||||||
# load my nix flake and add it to scope
|
|
||||||
nix-repl> :lf .
|
|
||||||
Added 16 variables.
|
|
||||||
|
|
||||||
# press <TAB> to see what we have in scope
|
|
||||||
nix-repl><TAB>
|
|
||||||
# ......omit some outputs
|
|
||||||
__isInt nixosConfigurations
|
|
||||||
__isList null
|
|
||||||
__isPath outPath
|
|
||||||
__isString outputs
|
|
||||||
__langVersion packages
|
|
||||||
# ......omit some outputs
|
|
||||||
|
|
||||||
|
|
||||||
# check what's in inputs
|
|
||||||
nix-repl> inputs.<TAB>
|
|
||||||
inputs.agenix inputs.nixpkgs
|
|
||||||
inputs.darwin inputs.nixpkgs-darwin
|
|
||||||
inputs.home-manager inputs.nixpkgs-unstable
|
|
||||||
inputs.hyprland inputs.nixpkgs-wayland
|
|
||||||
inputs.nil
|
|
||||||
inputs.nixos-generators
|
|
||||||
|
|
||||||
# check what's in inputs.nil
|
|
||||||
nix-repl> inputs.nil.packages.
|
|
||||||
inputs.nil.packages.aarch64-darwin
|
|
||||||
inputs.nil.packages.aarch64-linux
|
|
||||||
inputs.nil.packages.x86_64-darwin
|
|
||||||
inputs.nil.packages.x86_64-linux
|
|
||||||
|
|
||||||
# check the outputs of my nix flake
|
|
||||||
nix-repl> outputs.nixosConfigurations.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai
|
|
||||||
outputs.nixosConfigurations.aquamarine
|
|
||||||
outputs.nixosConfigurations.kana
|
|
||||||
outputs.nixosConfigurations.ruby
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai._module
|
|
||||||
outputs.nixosConfigurations.ai._type
|
|
||||||
outputs.nixosConfigurations.ai.class
|
|
||||||
outputs.nixosConfigurations.ai.config
|
|
||||||
outputs.nixosConfigurations.ai.extendModules
|
|
||||||
outputs.nixosConfigurations.ai.extraArgs
|
|
||||||
outputs.nixosConfigurations.ai.options
|
|
||||||
outputs.nixosConfigurations.ai.pkgs
|
|
||||||
outputs.nixosConfigurations.ai.type
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.
|
|
||||||
outputs.nixosConfigurations.ai.config.age
|
|
||||||
outputs.nixosConfigurations.ai.config.appstream
|
|
||||||
outputs.nixosConfigurations.ai.config.assertions
|
|
||||||
outputs.nixosConfigurations.ai.config.boot
|
|
||||||
outputs.nixosConfigurations.ai.config.console
|
|
||||||
outputs.nixosConfigurations.ai.config.containers
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activation
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activationPackage
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.emptyActivationPath
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableDebugInfo
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableNixpkgsReleaseCheck
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraActivationPath
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraBuilderCommands
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraOutputsToInstall
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraProfileCommands
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.BROWSER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.DELTA_PAGER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.EDITOR
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.GLFW_IM_MODULE
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.MANPAGER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.QT_IM_MODULE
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
# check the value of `TERM`
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
|
||||||
"xterm-256color"
|
|
||||||
|
|
||||||
|
|
||||||
# check all files defined by `home.file`
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bash_profile
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bashrc
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile-bak
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/config
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/i3blocks.conf
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/keybindings
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/layouts
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/scripts
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/wallpaper.png
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/rofi
|
|
||||||
#......
|
|
||||||
```
|
|
||||||
|
|
||||||
As you can see, we can check every attribute of my flake in the REPL after loading it, which is very convenient for debugging.
|
|
||||||
|
|
||||||
## 3. Remote deployment
|
|
||||||
|
|
||||||
Some tools like [NixOps](https://github.com/NixOS/nixops), [deploy-rs](https://github.com/serokell/deploy-rs), and [colmena](https://github.com/zhaofengli/colmena) can all be used to deploy NixOS configuration to remote hosts, but they are all too complicated for me, so skip them all.
|
|
||||||
|
|
||||||
`nixos-rebuild`, the tool we use to deploy NixOS configuration, also supports remote deployment through ssh protocol, which is very convenient and simple.
|
|
||||||
|
|
||||||
But `nixos-rebuild` does not support deploying with password authentication, so to use it for remote deployment, we need to:
|
|
||||||
|
|
||||||
1. Configure ssh public key authentication for the remote hosts.
|
|
||||||
2. To avoid sudo password verification failures, we need to use the `root` user to deploy, or grant the user sudo permission without password verification.
|
|
||||||
1. related issue: <https://github.com/NixOS/nixpkgs/issues/118655>
|
|
||||||
|
|
||||||
After the above configuration is completed, we can deploy the configuration to the server through the following command:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. add the ssh key to ssh-agent first
|
|
||||||
ssh-add ~/.ssh/ai-idols
|
|
||||||
|
|
||||||
# 2. deploy the configuration to the remote host, using the ssh key we added in step 1
|
|
||||||
# and the username defaults to `$USER`, it's `ryan` in my case.
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host 192.168.4.1 --build-host 192.168.4.1 switch --use-remote-sudo --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
The commands above will build & deploy the configuration to aquamarine, the build process will be executed on aquamarine too,
|
|
||||||
and the `--use-remote-sudo` option indicates that we need to use sudo permission on the remote server to deploy the configuration.
|
|
||||||
|
|
||||||
If you want to build the configuration locally and deploy it to the remote server, just replace `--build-host aquamarinr` with `--build-host localhost`.
|
|
||||||
|
|
||||||
Instead of use ip address directly, we can also define some host aliases in `~/.ssh/config` or `/etc/ssh/ssh_config`, for example:
|
|
||||||
|
|
||||||
> ssh's config can be generated completely through Nix configuration, and this task is left to you.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
› cat ~/.ssh/config
|
|
||||||
|
|
||||||
# ......
|
|
||||||
|
|
||||||
Host ai
|
|
||||||
HostName 192.168.5.100
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host aquamarine
|
|
||||||
HostName 192.168.5.101
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host ruby
|
|
||||||
HostName 192.168.5.102
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host kana
|
|
||||||
HostName 192.168.5.103
|
|
||||||
Port 22
|
|
||||||
```
|
|
||||||
|
|
||||||
Then we can use the host alias to deploy the configuration:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. Work with Makefile
|
|
||||||
|
|
||||||
> NOTE: Makefile's target name should not be the same as one of the file or directory in the current directory, otherwise the target will not be executed!
|
|
||||||
|
|
||||||
I use Makefile to manage the commands of my flake, which is very convenient.
|
|
||||||
|
|
||||||
For example, my Makefile looks like this:
|
|
||||||
|
|
||||||
```makefile
|
|
||||||
#
|
|
||||||
# NOTE: Makefile's target name should not be the same as one of the file or directory in the current directory,
|
|
||||||
# otherwise the target will not be executed!
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# Nix commands related to the local machine
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
nixos-rebuild switch --flake . --use-remote-sudo
|
|
||||||
|
|
||||||
debug:
|
|
||||||
nixos-rebuild switch --flake . --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
update:
|
|
||||||
nix flake update
|
|
||||||
|
|
||||||
history:
|
|
||||||
nix profile history --profile /nix/var/nix/profiles/system
|
|
||||||
|
|
||||||
gc:
|
|
||||||
# remove all generations older than 7 days
|
|
||||||
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
|
||||||
|
|
||||||
# garbage collect all unused nix store entries
|
|
||||||
sudo nix store gc --debug
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# Idols, Commands related to my remote distributed building cluster
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
add-idols-ssh-key:
|
|
||||||
ssh-add ~/.ssh/ai-idols
|
|
||||||
|
|
||||||
aqua: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo
|
|
||||||
|
|
||||||
aqua-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
ruby: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo
|
|
||||||
|
|
||||||
ruby-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
kana: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo
|
|
||||||
|
|
||||||
kana-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
idols: aqua ruby kana
|
|
||||||
|
|
||||||
idols-debug: aqua-debug ruby-debug kana-debug
|
|
||||||
```
|
|
||||||
|
|
||||||
Save the above Makefile to the root directory of the flake, and then we can use `make deploy` to deploy the configuration to the local machine, and use `make idols` to deploy the configuration to all my remote servers.
|
|
||||||
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- [Tips&Tricks for NixOS Desktop - NixOS Discourse][Tips&Tricks for NixOS Desktop - NixOS Discourse]
|
|
||||||
|
|
||||||
[Tips&Tricks for NixOS Desktop - NixOS Discourse]: https://discourse.nixos.org/t/tips-tricks-for-nixos-desktop/28488
|
|
11
docs/best-practices/intro.md
Normal file
11
docs/best-practices/intro.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
Nix is powerful and flexible, it provides a lot of ways to do things, making it difficult to find the most suitable way to do your job.
|
||||||
|
Here are some best practices that I've learned from the community, hope it can help you.
|
||||||
|
|
||||||
|
|
||||||
|
## 4.
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Tips&Tricks for NixOS Desktop - NixOS Discourse][Tips&Tricks for NixOS Desktop - NixOS Discourse]
|
||||||
|
|
||||||
|
[Tips&Tricks for NixOS Desktop - NixOS Discourse]: https://discourse.nixos.org/t/tips-tricks-for-nixos-desktop/28488
|
60
docs/best-practices/remote-deployment.md
Normal file
60
docs/best-practices/remote-deployment.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
|
||||||
|
## Remote deployment
|
||||||
|
|
||||||
|
Some tools like [NixOps](https://github.com/NixOS/nixops), [deploy-rs](https://github.com/serokell/deploy-rs), and [colmena](https://github.com/zhaofengli/colmena) can all be used to deploy NixOS configuration to remote hosts, but they are all too complicated for me.
|
||||||
|
|
||||||
|
`nixos-rebuild`, the tool we use to deploy NixOS configuration, also supports remote deployment through ssh protocol, which is very convenient and simple.
|
||||||
|
|
||||||
|
But `nixos-rebuild` does not support deploying with password authentication, so to use it for remote deployment, we need to:
|
||||||
|
|
||||||
|
1. Configure ssh public key authentication for the remote hosts.
|
||||||
|
2. To avoid sudo password verification failures, we need to use the `root` user to deploy, or grant the user sudo permission without password verification.
|
||||||
|
1. related issue: <https://github.com/NixOS/nixpkgs/issues/118655>
|
||||||
|
|
||||||
|
After the above configuration is completed, we can deploy the configuration to the server through the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. add the ssh key to ssh-agent first
|
||||||
|
ssh-add ~/.ssh/ai-idols
|
||||||
|
|
||||||
|
# 2. deploy the configuration to the remote host, using the ssh key we added in step 1
|
||||||
|
# and the username defaults to `$USER`, it's `ryan` in my case.
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host 192.168.4.1 --build-host 192.168.4.1 switch --use-remote-sudo --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
The commands above will build & deploy the configuration to aquamarine, the build process will be executed on aquamarine too,
|
||||||
|
and the `--use-remote-sudo` option indicates that we need to use sudo permission on the remote server to deploy the configuration.
|
||||||
|
|
||||||
|
If you want to build the configuration locally and deploy it to the remote server, just replace `--build-host aquamarinr` with `--build-host localhost`.
|
||||||
|
|
||||||
|
Instead of use ip address directly, we can also define some host aliases in `~/.ssh/config` or `/etc/ssh/ssh_config`, for example:
|
||||||
|
|
||||||
|
> ssh's config can be generated completely through Nix configuration, and this task is left to you.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› cat ~/.ssh/config
|
||||||
|
|
||||||
|
# ......
|
||||||
|
|
||||||
|
Host ai
|
||||||
|
HostName 192.168.5.100
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host aquamarine
|
||||||
|
HostName 192.168.5.101
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host ruby
|
||||||
|
HostName 192.168.5.102
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host kana
|
||||||
|
HostName 192.168.5.103
|
||||||
|
Port 22
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we can use the host alias to deploy the configuration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --verbose
|
||||||
|
```
|
58
docs/best-practices/run-downloaded-binaries-on-nixos.md
Normal file
58
docs/best-practices/run-downloaded-binaries-on-nixos.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
## Run downloaded binaries on NixOS
|
||||||
|
|
||||||
|
NixOS does not follow the FHS standard, so the binaries you download from the Internet will not likely work on NixOS. But there are some ways to make it work.
|
||||||
|
|
||||||
|
Here is a detailed guide which provides 10 ways to run downloaded binaries on NixOS: [Different methods to run a non-nixos executable on Nixos](https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos), I recommend you to read it.
|
||||||
|
|
||||||
|
Among these methods, I prefer creating a FHS environment to run the binary, which is very convenient and easy to use.
|
||||||
|
|
||||||
|
To create such an environment, add the following code to one of your nix modules:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# ......omit many configurations
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# ......omit many packages
|
||||||
|
|
||||||
|
# create a fhs environment by command `fhs`, so we can run non-nixos packages in nixos!
|
||||||
|
(pkgs.buildFHSUserEnv (base // {
|
||||||
|
name = "fhs";
|
||||||
|
targetPkgs = pkgs: (
|
||||||
|
# pkgs.buildFHSUserEnv provides only a minimal fhs environment,
|
||||||
|
# it lacks many basic packages needed by most softwares.
|
||||||
|
# so we need to add them manually.
|
||||||
|
#
|
||||||
|
# pkgs.appimageTools provides basic packages needed by most softwares.
|
||||||
|
(pkgs.appimageTools.defaultFhsEnvArgs.targetPkgs pkgs) ++ with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
ncurses
|
||||||
|
# feel free to add more packages here, if you need
|
||||||
|
]
|
||||||
|
);
|
||||||
|
profile = "export FHS=1";
|
||||||
|
runScript = "bash";
|
||||||
|
extraOutputsToInstall = ["dev"];
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
|
||||||
|
# ......omit many configurations
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
after applying the updated configuration, you can run `fhs` to enter the FHS environment, and then run the binary you downloaded, e.g.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Activating FHS drops me in a shell which looks like a "normal" Linux
|
||||||
|
$ fhs
|
||||||
|
# check what we have in /usr/bin
|
||||||
|
(fhs) $ ls /usr/bin
|
||||||
|
# try to run a non-nixos binary downloaded from the Internet
|
||||||
|
(fhs) $ ./bin/code
|
||||||
|
```
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Tips&Tricks for NixOS Desktop - NixOS Discourse][Tips&Tricks for NixOS Desktop - NixOS Discourse]: Just as the title says, it is a collection of tips and tricks for NixOS desktop.
|
72
docs/best-practices/simplify-nixos-related-commands.md
Normal file
72
docs/best-practices/simplify-nixos-related-commands.md
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
## Simplify nixos-related commands
|
||||||
|
|
||||||
|
I use Makefile to simplify nixos-related commands, which is very convenient.
|
||||||
|
You can also use other similar tools to do this job, here I will only introduce my usage as a reference.
|
||||||
|
|
||||||
|
My Makefile looks like this:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
#
|
||||||
|
# NOTE: Makefile's target name should not be the same as one of the file or directory in the current directory,
|
||||||
|
# otherwise the target will not be executed!
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Nix commands related to the local machine
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
nixos-rebuild switch --flake . --use-remote-sudo
|
||||||
|
|
||||||
|
debug:
|
||||||
|
nixos-rebuild switch --flake . --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
update:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
history:
|
||||||
|
nix profile history --profile /nix/var/nix/profiles/system
|
||||||
|
|
||||||
|
gc:
|
||||||
|
# remove all generations older than 7 days
|
||||||
|
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
||||||
|
|
||||||
|
# garbage collect all unused nix store entries
|
||||||
|
sudo nix store gc --debug
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Idols, Commands related to my remote distributed building cluster
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
add-idols-ssh-key:
|
||||||
|
ssh-add ~/.ssh/ai-idols
|
||||||
|
|
||||||
|
aqua: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo
|
||||||
|
|
||||||
|
aqua-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
ruby: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo
|
||||||
|
|
||||||
|
ruby-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
kana: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo
|
||||||
|
|
||||||
|
kana-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
idols: aqua ruby kana
|
||||||
|
|
||||||
|
idols-debug: aqua-debug ruby-debug kana-debug
|
||||||
|
```
|
||||||
|
|
||||||
|
Save the above Makefile to the root directory of the flake, and then we can use `make deploy` to deploy the configuration to the local machine, and use `make idols` to deploy the configuration to all my remote servers.
|
153
docs/zh/best-practices/debug-with-nix-repl.md
Normal file
153
docs/zh/best-practices/debug-with-nix-repl.md
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
|
||||||
|
## 通过 `nix repl` 查看源码、调试配置 {#view-source-code-via-nix-repl}
|
||||||
|
|
||||||
|
前面我们已经使用 `nix repl '<nixpkgs>'` 看过很多次源码了,这是一个非常强大的工具,可以帮助我们理解 Nix 的工作原理。
|
||||||
|
|
||||||
|
要学会用 `nix repl`,最好先看看它的 help 信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
› nix repl -f '<nixpkgs>'
|
||||||
|
Welcome to Nix 2.13.3. Type :? for help.
|
||||||
|
|
||||||
|
Loading installable ''...
|
||||||
|
Added 17755 variables.
|
||||||
|
nix-repl> :?
|
||||||
|
The following commands are available:
|
||||||
|
|
||||||
|
<expr> Evaluate and print expression
|
||||||
|
<x> = <expr> Bind expression to variable
|
||||||
|
:a <expr> Add attributes from resulting set to scope
|
||||||
|
:b <expr> Build a derivation
|
||||||
|
:bl <expr> Build a derivation, creating GC roots in the working directory
|
||||||
|
:e <expr> Open package or function in $EDITOR
|
||||||
|
:i <expr> Build derivation, then install result into current profile
|
||||||
|
:l <path> Load Nix expression and add it to scope
|
||||||
|
:lf <ref> Load Nix flake and add it to scope
|
||||||
|
:p <expr> Evaluate and print expression recursively
|
||||||
|
:q Exit nix-repl
|
||||||
|
:r Reload all files
|
||||||
|
:sh <expr> Build dependencies of derivation, then start nix-shell
|
||||||
|
:t <expr> Describe result of evaluation
|
||||||
|
:u <expr> Build derivation, then start nix-shell
|
||||||
|
:doc <expr> Show documentation of a builtin function
|
||||||
|
:log <expr> Show logs for a derivation
|
||||||
|
:te [bool] Enable, disable or toggle showing traces for errors
|
||||||
|
```
|
||||||
|
|
||||||
|
我最常用的命令是 `:lf <ref>` 跟 `:e <expr>`.
|
||||||
|
|
||||||
|
`:e <expr>` 非常直观,所以这里不再赘述,我们来看看 `:lf <ref>`:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
# 进入我的 nix 配置目录(建议替换成你自己的配置目录)
|
||||||
|
› cd ~/nix-config/
|
||||||
|
|
||||||
|
# 进入 nix repl 解释器
|
||||||
|
› nix repl
|
||||||
|
Welcome to Nix 2.13.3. Type :? for help.
|
||||||
|
|
||||||
|
# 将我的 nix 配置作为一个 flake 加载到当前作用域中
|
||||||
|
nix-repl> :lf .
|
||||||
|
Added 16 variables.
|
||||||
|
|
||||||
|
# 按 <TAB> 看看当前作用域中有哪些变量,果然 nixosConfigurations inputs outputs 跟 packages 都在里面
|
||||||
|
# 这意味着我们可以很方便地检查这些配置的内部状态
|
||||||
|
nix-repl><TAB>
|
||||||
|
# ......omit some outputs
|
||||||
|
__isInt nixosConfigurations
|
||||||
|
__isList null
|
||||||
|
__isPath outPath
|
||||||
|
__isString outputs
|
||||||
|
__langVersion packages
|
||||||
|
# ......omit some outputs
|
||||||
|
|
||||||
|
# 看看 inputs 里都有些啥
|
||||||
|
nix-repl> inputs.<TAB>
|
||||||
|
inputs.agenix inputs.nixpkgs
|
||||||
|
inputs.darwin inputs.nixpkgs-darwin
|
||||||
|
inputs.home-manager inputs.nixpkgs-unstable
|
||||||
|
inputs.hyprland inputs.nixpkgs-wayland
|
||||||
|
inputs.nil
|
||||||
|
inputs.nixos-generators
|
||||||
|
|
||||||
|
# 看看 inputs.nil.packages 里都有些啥
|
||||||
|
nix-repl> inputs.nil.packages.
|
||||||
|
inputs.nil.packages.aarch64-darwin
|
||||||
|
inputs.nil.packages.aarch64-linux
|
||||||
|
inputs.nil.packages.x86_64-darwin
|
||||||
|
inputs.nil.packages.x86_64-linux
|
||||||
|
|
||||||
|
# 看看 outputs 里都有些啥
|
||||||
|
nix-repl> outputs.nixosConfigurations.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai
|
||||||
|
outputs.nixosConfigurations.aquamarine
|
||||||
|
outputs.nixosConfigurations.kana
|
||||||
|
outputs.nixosConfigurations.ruby
|
||||||
|
|
||||||
|
# 看看 ai 的配置都有些啥
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai._module
|
||||||
|
outputs.nixosConfigurations.ai._type
|
||||||
|
outputs.nixosConfigurations.ai.class
|
||||||
|
outputs.nixosConfigurations.ai.config
|
||||||
|
outputs.nixosConfigurations.ai.extendModules
|
||||||
|
outputs.nixosConfigurations.ai.extraArgs
|
||||||
|
outputs.nixosConfigurations.ai.options
|
||||||
|
outputs.nixosConfigurations.ai.pkgs
|
||||||
|
outputs.nixosConfigurations.ai.type
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.
|
||||||
|
outputs.nixosConfigurations.ai.config.age
|
||||||
|
outputs.nixosConfigurations.ai.config.appstream
|
||||||
|
outputs.nixosConfigurations.ai.config.assertions
|
||||||
|
outputs.nixosConfigurations.ai.config.boot
|
||||||
|
outputs.nixosConfigurations.ai.config.console
|
||||||
|
outputs.nixosConfigurations.ai.config.containers
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activation
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activationPackage
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.emptyActivationPath
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableDebugInfo
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableNixpkgsReleaseCheck
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraActivationPath
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraBuilderCommands
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraOutputsToInstall
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraProfileCommands
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.BROWSER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.DELTA_PAGER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.EDITOR
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.GLFW_IM_MODULE
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.MANPAGER
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.QT_IM_MODULE
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
||||||
|
# ......omit other outputs
|
||||||
|
|
||||||
|
# 看看 `TERM` 这个环境变量的值是啥
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
||||||
|
"xterm-256color"
|
||||||
|
|
||||||
|
|
||||||
|
# 看下我使用 `home.file` 定义的所有文件
|
||||||
|
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file.<TAB>
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bash_profile
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bashrc
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile-bak
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/config
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/i3blocks.conf
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/keybindings
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/layouts
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/scripts
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/wallpaper.png
|
||||||
|
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/rofi
|
||||||
|
#......
|
||||||
|
```
|
||||||
|
|
||||||
|
能看到,通过 `nix repl` 加载好我的 flake 配置后,就能很方便地检查所有的配置项了,这对于调试非常有用。
|
@ -1,346 +0,0 @@
|
|||||||
|
|
||||||
## 十一、最佳实践 {#best-practices}
|
|
||||||
|
|
||||||
> [Tips&Tricks for NixOS Desktop - NixOS Discourse][Tips&Tricks for NixOS Desktop - NixOS Discourse]
|
|
||||||
|
|
||||||
Nix 非常强大且灵活,做一件事有非常多的方法,这就导致了很难找到最合适的方法来做你的工作。
|
|
||||||
这里记录了一些我在使用 NixOS 中学习到的最佳实践,希望能帮到你。
|
|
||||||
|
|
||||||
### 1. 运行非 NixOS 的二进制文件 {#run-non-nixos-binaries}
|
|
||||||
|
|
||||||
NixOS 不遵循 FHS 标准,因此你从网上下载的二进制程序在 NixOS 上大概率是跑不了的。
|
|
||||||
为了在 NixOS 上跑这些非 NixOS 的二进制程序,需要做一些骚操作。有位老兄在这里总结了 10 种实现此目的的方法:[Different methods to run a non-nixos executable on Nixos](https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos),推荐一读。
|
|
||||||
|
|
||||||
我个人用的比较多的方法是,直接创建一个 FHS 环境来运行二进制程序,这种方法非常方便易用。
|
|
||||||
|
|
||||||
大概玩法是这样的,首先在你的 `environment.systemPackages` 中添加这个包:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ config, pkgs, lib, ... }:
|
|
||||||
|
|
||||||
{
|
|
||||||
# ......
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# ......o
|
|
||||||
|
|
||||||
# create a fhs environment by command `fhs`, so we can run non-nixos packages in nixos!
|
|
||||||
(pkgs.buildFHSUserEnv (base // {
|
|
||||||
name = "fhs";
|
|
||||||
targetPkgs = pkgs: (
|
|
||||||
# pkgs.buildFHSUserEnv 只提供一个最小的 FHS 环境,缺少很多常用软件所必须的基础包
|
|
||||||
# 所以直接使用它很可能会报错
|
|
||||||
#
|
|
||||||
# pkgs.appimageTools 提供了大多数程序常用的基础包,所以我们可以直接用它来补充
|
|
||||||
(pkgs.appimageTools.defaultFhsEnvArgs.targetPkgs pkgs) ++ with pkgs; [
|
|
||||||
pkg-config
|
|
||||||
ncurses
|
|
||||||
# 如果你的 FHS 程序还有其他依赖,把它们添加在这里
|
|
||||||
]
|
|
||||||
);
|
|
||||||
profile = "export FHS=1";
|
|
||||||
runScript = "bash";
|
|
||||||
extraOutputsToInstall = ["dev"];
|
|
||||||
}))
|
|
||||||
];
|
|
||||||
|
|
||||||
# ......
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
部署好上面的配置后,你就能用 `fhs` 命令进入我们定义好的 FHS 环境了,然后就可以运行你下载的二进制程序了,比如:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# 进入我们定义好的 fhs 环境,它就跟其他 Linux 发行版一样了
|
|
||||||
$ fhs
|
|
||||||
# 看看我们的 /usr/bin 里是不是多了很多东西
|
|
||||||
(fhs) $ ls /usr/bin
|
|
||||||
# 尝试下跑一个非 nixos 的二进制程序
|
|
||||||
(fhs) $ ./bin/code
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 通过 `nix repl` 查看源码、调试配置 {#view-source-code-via-nix-repl}
|
|
||||||
|
|
||||||
前面我们已经使用 `nix repl '<nixpkgs>'` 看过很多次源码了,这是一个非常强大的工具,可以帮助我们理解 Nix 的工作原理。
|
|
||||||
|
|
||||||
要学会用 `nix repl`,最好先看看它的 help 信息:
|
|
||||||
|
|
||||||
```
|
|
||||||
› nix repl -f '<nixpkgs>'
|
|
||||||
Welcome to Nix 2.13.3. Type :? for help.
|
|
||||||
|
|
||||||
Loading installable ''...
|
|
||||||
Added 17755 variables.
|
|
||||||
nix-repl> :?
|
|
||||||
The following commands are available:
|
|
||||||
|
|
||||||
<expr> Evaluate and print expression
|
|
||||||
<x> = <expr> Bind expression to variable
|
|
||||||
:a <expr> Add attributes from resulting set to scope
|
|
||||||
:b <expr> Build a derivation
|
|
||||||
:bl <expr> Build a derivation, creating GC roots in the working directory
|
|
||||||
:e <expr> Open package or function in $EDITOR
|
|
||||||
:i <expr> Build derivation, then install result into current profile
|
|
||||||
:l <path> Load Nix expression and add it to scope
|
|
||||||
:lf <ref> Load Nix flake and add it to scope
|
|
||||||
:p <expr> Evaluate and print expression recursively
|
|
||||||
:q Exit nix-repl
|
|
||||||
:r Reload all files
|
|
||||||
:sh <expr> Build dependencies of derivation, then start nix-shell
|
|
||||||
:t <expr> Describe result of evaluation
|
|
||||||
:u <expr> Build derivation, then start nix-shell
|
|
||||||
:doc <expr> Show documentation of a builtin function
|
|
||||||
:log <expr> Show logs for a derivation
|
|
||||||
:te [bool] Enable, disable or toggle showing traces for errors
|
|
||||||
```
|
|
||||||
|
|
||||||
我最常用的命令是 `:lf <ref>` 跟 `:e <expr>`.
|
|
||||||
|
|
||||||
`:e <expr>` 非常直观,所以这里不再赘述,我们来看看 `:lf <ref>`:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# 进入我的 nix 配置目录(建议替换成你自己的配置目录)
|
|
||||||
› cd ~/nix-config/
|
|
||||||
|
|
||||||
# 进入 nix repl 解释器
|
|
||||||
› nix repl
|
|
||||||
Welcome to Nix 2.13.3. Type :? for help.
|
|
||||||
|
|
||||||
# 将我的 nix 配置作为一个 flake 加载到当前作用域中
|
|
||||||
nix-repl> :lf .
|
|
||||||
Added 16 variables.
|
|
||||||
|
|
||||||
# 按 <TAB> 看看当前作用域中有哪些变量,果然 nixosConfigurations inputs outputs 跟 packages 都在里面
|
|
||||||
# 这意味着我们可以很方便地检查这些配置的内部状态
|
|
||||||
nix-repl><TAB>
|
|
||||||
# ......omit some outputs
|
|
||||||
__isInt nixosConfigurations
|
|
||||||
__isList null
|
|
||||||
__isPath outPath
|
|
||||||
__isString outputs
|
|
||||||
__langVersion packages
|
|
||||||
# ......omit some outputs
|
|
||||||
|
|
||||||
# 看看 inputs 里都有些啥
|
|
||||||
nix-repl> inputs.<TAB>
|
|
||||||
inputs.agenix inputs.nixpkgs
|
|
||||||
inputs.darwin inputs.nixpkgs-darwin
|
|
||||||
inputs.home-manager inputs.nixpkgs-unstable
|
|
||||||
inputs.hyprland inputs.nixpkgs-wayland
|
|
||||||
inputs.nil
|
|
||||||
inputs.nixos-generators
|
|
||||||
|
|
||||||
# 看看 inputs.nil.packages 里都有些啥
|
|
||||||
nix-repl> inputs.nil.packages.
|
|
||||||
inputs.nil.packages.aarch64-darwin
|
|
||||||
inputs.nil.packages.aarch64-linux
|
|
||||||
inputs.nil.packages.x86_64-darwin
|
|
||||||
inputs.nil.packages.x86_64-linux
|
|
||||||
|
|
||||||
# 看看 outputs 里都有些啥
|
|
||||||
nix-repl> outputs.nixosConfigurations.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai
|
|
||||||
outputs.nixosConfigurations.aquamarine
|
|
||||||
outputs.nixosConfigurations.kana
|
|
||||||
outputs.nixosConfigurations.ruby
|
|
||||||
|
|
||||||
# 看看 ai 的配置都有些啥
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai._module
|
|
||||||
outputs.nixosConfigurations.ai._type
|
|
||||||
outputs.nixosConfigurations.ai.class
|
|
||||||
outputs.nixosConfigurations.ai.config
|
|
||||||
outputs.nixosConfigurations.ai.extendModules
|
|
||||||
outputs.nixosConfigurations.ai.extraArgs
|
|
||||||
outputs.nixosConfigurations.ai.options
|
|
||||||
outputs.nixosConfigurations.ai.pkgs
|
|
||||||
outputs.nixosConfigurations.ai.type
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.
|
|
||||||
outputs.nixosConfigurations.ai.config.age
|
|
||||||
outputs.nixosConfigurations.ai.config.appstream
|
|
||||||
outputs.nixosConfigurations.ai.config.assertions
|
|
||||||
outputs.nixosConfigurations.ai.config.boot
|
|
||||||
outputs.nixosConfigurations.ai.config.console
|
|
||||||
outputs.nixosConfigurations.ai.config.containers
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activation
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.activationPackage
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.emptyActivationPath
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableDebugInfo
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.enableNixpkgsReleaseCheck
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraActivationPath
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraBuilderCommands
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraOutputsToInstall
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.extraProfileCommands
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.BROWSER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.DELTA_PAGER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.EDITOR
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.GLFW_IM_MODULE
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.MANPAGER
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.QT_IM_MODULE
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
|
||||||
# ......omit other outputs
|
|
||||||
|
|
||||||
# 看看 `TERM` 这个环境变量的值是啥
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.sessionVariables.TERM
|
|
||||||
"xterm-256color"
|
|
||||||
|
|
||||||
|
|
||||||
# 看下我使用 `home.file` 定义的所有文件
|
|
||||||
nix-repl> outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file.<TAB>
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bash_profile
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..bashrc
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/fcitx5/profile-bak
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/config
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/i3blocks.conf
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/keybindings
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/layouts
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/scripts
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/i3/wallpaper.png
|
|
||||||
outputs.nixosConfigurations.ai.config.home-manager.users.ryan.home.file..config/rofi
|
|
||||||
#......
|
|
||||||
```
|
|
||||||
|
|
||||||
能看到,通过 `nix repl` 加载好我的 flake 配置后,就能很方便地检查所有的配置项了,这对于调试非常有用。
|
|
||||||
|
|
||||||
### 3. 远程部署
|
|
||||||
|
|
||||||
社区的一些工具,比如 [NixOps](https://github.com/NixOS/nixops), [deploy-rs](https://github.com/serokell/deploy-rs), 跟 [colmena](https://github.com/zhaofengli/colmena),都可以用来部署 NixOS 配置到远程主机,但是都太复杂了,所以先全部跳过。
|
|
||||||
|
|
||||||
实际上我们前面使用了多次的 NixOS 本机部署命令 `nixos-rebuild`,这个工具也支持通过 ssh 协议进行远程部署,非常方便。
|
|
||||||
|
|
||||||
美中不足的是,`nixos-rebuild` 不支持使用密码认证进行部署,所以要想使用它进行远程部署,我们需要:
|
|
||||||
|
|
||||||
1. 为远程主机配置 ssh 公钥认证。
|
|
||||||
2. 为了避免 sudo 密码认证失败,需要使用 `root` 用户进行部署,或者给用户授予 sudo 权限不需要密码认证。
|
|
||||||
1. 相关 issue: <https://github.com/NixOS/nixpkgs/issues/118655>
|
|
||||||
|
|
||||||
在搞定上面两点后,我们就可以使用 `nixos-rebuild` 进行远程部署了:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 首先将本地的 ssh 私钥加载到 ssh-agent 中,以便后续使用
|
|
||||||
ssh-add ~/.ssh/ai-idols
|
|
||||||
|
|
||||||
# 2. 将 NixOS 配置部署到远程主机,使用第一步添加的 ssh key 进行认证,用户名默认为 `$USER`
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host 192.168.4.1 --build-host 192.168.4.1 switch --use-remote-sudo --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
上面的命令会将 NixOS 配置部署到 `aquamarine` 这台主机上,参数解释如下:
|
|
||||||
|
|
||||||
1. `--target-host`: 设置远程主机的 ip 地址
|
|
||||||
2. `--build-host` 指定了构建 NixOS 配置的主机,这里设置为跟 `--target-host` 相同,表示在远程主机上构建配置。
|
|
||||||
3. `--use-remote-sudo` 表示部署需要用到远程主机的 sudo 权限,如果不设置这个参数,部署会失败。
|
|
||||||
|
|
||||||
如果你希望在本地构建配置,然后再部署到远程主机,可以命令中的 `--build-host aquamarinr` 替换为 `--build-host localhost`。
|
|
||||||
|
|
||||||
另外如果你不想直接使用 ip 地址,可以在 `~/.ssh/config` 或者 `/etc/ssh/ssh_config` 中定义一些主机别名,比如:
|
|
||||||
|
|
||||||
> 当然如下这份配置也完全可以通过 Nix 来管理,这个就留给读者自己去实现了。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
› cat ~/.ssh/config
|
|
||||||
|
|
||||||
# ......
|
|
||||||
|
|
||||||
Host ai
|
|
||||||
HostName 192.168.5.100
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host aquamarine
|
|
||||||
HostName 192.168.5.101
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host ruby
|
|
||||||
HostName 192.168.5.102
|
|
||||||
Port 22
|
|
||||||
|
|
||||||
Host kana
|
|
||||||
HostName 192.168.5.103
|
|
||||||
Port 22
|
|
||||||
```
|
|
||||||
|
|
||||||
这样我们就可以使用主机别名进行部署了:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --verbose
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 使用 Makefile 简化命令
|
|
||||||
|
|
||||||
> 注意: Makefile 的 target 名称不能与当前目录下的文件或者目录重名,否则 target 将不会被执行!
|
|
||||||
|
|
||||||
在使用 NixOS 的过程中,我们会经常使用 `nixos-rebuild` 命令,经常需要输入一大堆参数,比较繁琐。
|
|
||||||
|
|
||||||
所以我使用 Makefile 来管理我的 flake 配置相关的命令,简化使用。
|
|
||||||
|
|
||||||
我的 Makefile 大概内容截取如下:
|
|
||||||
|
|
||||||
```makefile
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# Nix commands related to the local machine
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
nixos-rebuild switch --flake . --use-remote-sudo
|
|
||||||
|
|
||||||
debug:
|
|
||||||
nixos-rebuild switch --flake . --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
update:
|
|
||||||
nix flake update
|
|
||||||
|
|
||||||
history:
|
|
||||||
nix profile history --profile /nix/var/nix/profiles/system
|
|
||||||
|
|
||||||
gc:
|
|
||||||
# remove all generations older than 7 days
|
|
||||||
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
|
||||||
|
|
||||||
# garbage collect all unused nix store entries
|
|
||||||
sudo nix store gc --debug
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
#
|
|
||||||
# Idols, Commands related to my remote distributed building cluster
|
|
||||||
#
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
add-idols-ssh-key:
|
|
||||||
ssh-add ~/.ssh/ai-idols
|
|
||||||
|
|
||||||
aqua: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo
|
|
||||||
|
|
||||||
aqua-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
ruby: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo
|
|
||||||
|
|
||||||
ruby-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
kana: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo
|
|
||||||
|
|
||||||
kana-debug: add-idols-ssh-key
|
|
||||||
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo --show-trace --verbose
|
|
||||||
|
|
||||||
idols: aqua ruby kana
|
|
||||||
|
|
||||||
idols-debug: aqua-debug ruby-debug kana-debug
|
|
||||||
```
|
|
||||||
|
|
||||||
将上述 Makefile 放到 NixOS 配置的根目录下,然后我们就可以使用 `make` 命令来执行相关的命令了。
|
|
||||||
比如说我这里 `make deploy` 就是部署 NixOS 配置到本地主机,`make idols` 就是部署到我的远程主机集群。
|
|
5
docs/zh/best-practices/intro.md
Normal file
5
docs/zh/best-practices/intro.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
## 最佳实践 {#best-practices}
|
||||||
|
|
||||||
|
Nix 非常强大且灵活,做一件事有非常多的方法,这就导致了很难找到最合适的方法来做你的工作。
|
||||||
|
这里记录了一些我在使用 NixOS 中学习到的最佳实践,希望能帮到你。
|
62
docs/zh/best-practices/remote-deployment.md
Normal file
62
docs/zh/best-practices/remote-deployment.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
## 远程部署
|
||||||
|
|
||||||
|
社区的一些工具,比如 [NixOps](https://github.com/NixOS/nixops), [deploy-rs](https://github.com/serokell/deploy-rs), 跟 [colmena](https://github.com/zhaofengli/colmena),都可以用来部署 NixOS 配置到远程主机,但是都太复杂了,所以先全部跳过。
|
||||||
|
|
||||||
|
实际上我们前面使用了多次的 NixOS 本机部署命令 `nixos-rebuild`,这个工具也支持通过 ssh 协议进行远程部署,非常方便。
|
||||||
|
|
||||||
|
美中不足的是,`nixos-rebuild` 不支持使用密码认证进行部署,所以要想使用它进行远程部署,我们需要:
|
||||||
|
|
||||||
|
1. 为远程主机配置 ssh 公钥认证。
|
||||||
|
2. 为了避免 sudo 密码认证失败,需要使用 `root` 用户进行部署,或者给用户授予 sudo 权限不需要密码认证。
|
||||||
|
1. 相关 issue: <https://github.com/NixOS/nixpkgs/issues/118655>
|
||||||
|
|
||||||
|
在搞定上面两点后,我们就可以使用 `nixos-rebuild` 进行远程部署了:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 首先将本地的 ssh 私钥加载到 ssh-agent 中,以便后续使用
|
||||||
|
ssh-add ~/.ssh/ai-idols
|
||||||
|
|
||||||
|
# 2. 将 NixOS 配置部署到远程主机,使用第一步添加的 ssh key 进行认证,用户名默认为 `$USER`
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host 192.168.4.1 --build-host 192.168.4.1 switch --use-remote-sudo --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
上面的命令会将 NixOS 配置部署到 `aquamarine` 这台主机上,参数解释如下:
|
||||||
|
|
||||||
|
1. `--target-host`: 设置远程主机的 ip 地址
|
||||||
|
2. `--build-host` 指定了构建 NixOS 配置的主机,这里设置为跟 `--target-host` 相同,表示在远程主机上构建配置。
|
||||||
|
3. `--use-remote-sudo` 表示部署需要用到远程主机的 sudo 权限,如果不设置这个参数,部署会失败。
|
||||||
|
|
||||||
|
如果你希望在本地构建配置,然后再部署到远程主机,可以命令中的 `--build-host aquamarinr` 替换为 `--build-host localhost`。
|
||||||
|
|
||||||
|
另外如果你不想直接使用 ip 地址,可以在 `~/.ssh/config` 或者 `/etc/ssh/ssh_config` 中定义一些主机别名,比如:
|
||||||
|
|
||||||
|
> 当然如下这份配置也完全可以通过 Nix 来管理,这个就留给读者自己去实现了。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
› cat ~/.ssh/config
|
||||||
|
|
||||||
|
# ......
|
||||||
|
|
||||||
|
Host ai
|
||||||
|
HostName 192.168.5.100
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host aquamarine
|
||||||
|
HostName 192.168.5.101
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host ruby
|
||||||
|
HostName 192.168.5.102
|
||||||
|
Port 22
|
||||||
|
|
||||||
|
Host kana
|
||||||
|
HostName 192.168.5.103
|
||||||
|
Port 22
|
||||||
|
```
|
||||||
|
|
||||||
|
这样我们就可以使用主机别名进行部署了:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --verbose
|
||||||
|
```
|
56
docs/zh/best-practices/run-downloaded-binaries-on-nixos.md
Normal file
56
docs/zh/best-practices/run-downloaded-binaries-on-nixos.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
## 运行非 NixOS 的二进制文件 {#run-non-nixos-binaries}
|
||||||
|
|
||||||
|
NixOS 不遵循 FHS 标准,因此你从网上下载的二进制程序在 NixOS 上大概率是跑不了的。
|
||||||
|
为了在 NixOS 上跑这些非 NixOS 的二进制程序,需要做一些骚操作。有位老兄在这里总结了 10 种实现此目的的方法:[Different methods to run a non-nixos executable on Nixos](https://unix.stackexchange.com/questions/522822/different-methods-to-run-a-non-nixos-executable-on-nixos),推荐一读。
|
||||||
|
|
||||||
|
我个人用的比较多的方法是,直接创建一个 FHS 环境来运行二进制程序,这种方法非常方便易用。
|
||||||
|
|
||||||
|
大概玩法是这样的,首先在你的 `environment.systemPackages` 中添加这个包:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
# ......
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
# ......o
|
||||||
|
|
||||||
|
# create a fhs environment by command `fhs`, so we can run non-nixos packages in nixos!
|
||||||
|
(pkgs.buildFHSUserEnv (base // {
|
||||||
|
name = "fhs";
|
||||||
|
targetPkgs = pkgs: (
|
||||||
|
# pkgs.buildFHSUserEnv 只提供一个最小的 FHS 环境,缺少很多常用软件所必须的基础包
|
||||||
|
# 所以直接使用它很可能会报错
|
||||||
|
#
|
||||||
|
# pkgs.appimageTools 提供了大多数程序常用的基础包,所以我们可以直接用它来补充
|
||||||
|
(pkgs.appimageTools.defaultFhsEnvArgs.targetPkgs pkgs) ++ with pkgs; [
|
||||||
|
pkg-config
|
||||||
|
ncurses
|
||||||
|
# 如果你的 FHS 程序还有其他依赖,把它们添加在这里
|
||||||
|
]
|
||||||
|
);
|
||||||
|
profile = "export FHS=1";
|
||||||
|
runScript = "bash";
|
||||||
|
extraOutputsToInstall = ["dev"];
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
|
||||||
|
# ......
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
部署好上面的配置后,你就能用 `fhs` 命令进入我们定义好的 FHS 环境了,然后就可以运行你下载的二进制程序了,比如:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 进入我们定义好的 fhs 环境,它就跟其他 Linux 发行版一样了
|
||||||
|
$ fhs
|
||||||
|
# 看看我们的 /usr/bin 里是不是多了很多东西
|
||||||
|
(fhs) $ ls /usr/bin
|
||||||
|
# 尝试下跑一个非 nixos 的二进制程序
|
||||||
|
(fhs) $ ./bin/code
|
||||||
|
```
|
||||||
|
|
||||||
|
## 参考
|
||||||
|
|
||||||
|
- [Tips&Tricks for NixOS Desktop - NixOS Discourse][Tips&Tricks for NixOS Desktop - NixOS Discourse]: Just as the title says, it is a collection of tips and tricks for NixOS desktop.
|
71
docs/zh/best-practices/simplify-nixos-related-commands.md
Normal file
71
docs/zh/best-practices/simplify-nixos-related-commands.md
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
## 使用 Makefile 简化命令
|
||||||
|
|
||||||
|
> 注意: Makefile 的 target 名称不能与当前目录下的文件或者目录重名,否则 target 将不会被执行!
|
||||||
|
|
||||||
|
在使用 NixOS 的过程中,我们会经常使用 `nixos-rebuild` 命令,经常需要输入一大堆参数,比较繁琐。
|
||||||
|
|
||||||
|
所以我使用 Makefile 来管理我的 flake 配置相关的命令,简化使用。
|
||||||
|
|
||||||
|
我的 Makefile 大概内容截取如下:
|
||||||
|
|
||||||
|
```makefile
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Nix commands related to the local machine
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
nixos-rebuild switch --flake . --use-remote-sudo
|
||||||
|
|
||||||
|
debug:
|
||||||
|
nixos-rebuild switch --flake . --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
update:
|
||||||
|
nix flake update
|
||||||
|
|
||||||
|
history:
|
||||||
|
nix profile history --profile /nix/var/nix/profiles/system
|
||||||
|
|
||||||
|
gc:
|
||||||
|
# remove all generations older than 7 days
|
||||||
|
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 7d
|
||||||
|
|
||||||
|
# garbage collect all unused nix store entries
|
||||||
|
sudo nix store gc --debug
|
||||||
|
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Idols, Commands related to my remote distributed building cluster
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
add-idols-ssh-key:
|
||||||
|
ssh-add ~/.ssh/ai-idols
|
||||||
|
|
||||||
|
aqua: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo
|
||||||
|
|
||||||
|
aqua-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#aquamarine --target-host aquamarine --build-host aquamarine switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
ruby: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo
|
||||||
|
|
||||||
|
ruby-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#ruby --target-host ruby --build-host ruby switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
kana: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo
|
||||||
|
|
||||||
|
kana-debug: add-idols-ssh-key
|
||||||
|
nixos-rebuild --flake .#kana --target-host kana --build-host kana switch --use-remote-sudo --show-trace --verbose
|
||||||
|
|
||||||
|
idols: aqua ruby kana
|
||||||
|
|
||||||
|
idols-debug: aqua-debug ruby-debug kana-debug
|
||||||
|
```
|
||||||
|
|
||||||
|
将上述 Makefile 放到 NixOS 配置的根目录下,然后我们就可以使用 `make` 命令来执行相关的命令了。
|
||||||
|
比如说我这里 `make deploy` 就是部署 NixOS 配置到本地主机,`make idols` 就是部署到我的远程主机集群。
|
@ -1,151 +0,0 @@
|
|||||||
|
|
||||||
## 七、Nix Flakes 的使用 {#nix-flakes-usage}
|
|
||||||
|
|
||||||
到这里我们已经写了不少 Nix Flakes 配置来管理 NixOS 系统了,这里再简单介绍下 Nix Flakes 更细节的内容,以及常用的 nix flake 命令。
|
|
||||||
|
|
||||||
### 1. Flake 的 inputs {#flake-inputs}
|
|
||||||
|
|
||||||
`flake.nix` 中的 `inputs` 是一个 attribute set,用来指定当前 Flake 的依赖,inputs 有很多种类型,举例如下:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{
|
|
||||||
inputs = {
|
|
||||||
# 以 GitHub 仓库为数据源,指定使用 master 分支,这是最常见的 input 格式
|
|
||||||
nixpkgs.url = "github:Mic92/nixpkgs/master";
|
|
||||||
# Git URL,可用于任何基于 https/ssh 协议的 Git 仓库
|
|
||||||
git-example.url = "git+https://git.somehost.tld/user/path?ref=branch&rev=fdc8ef970de2b4634e1b3dca296e1ed918459a9e";
|
|
||||||
# 上面的例子会复制 .git 到本地, 如果数据量较大,建议使用 shallow=1 参数避免复制 .git
|
|
||||||
git-directory-example.url = "git+file:/path/to/repo?shallow=1";
|
|
||||||
# 本地文件夹 (如果使用绝对路径,可省略掉前缀 'path:')
|
|
||||||
directory-example.url = "path:/path/to/repo";
|
|
||||||
# 如果数据源不是一个 flake,则需要设置 flake=false
|
|
||||||
bar = {
|
|
||||||
url = "github:foo/bar/branch";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
sops-nix = {
|
|
||||||
url = "github:Mic92/sops-nix";
|
|
||||||
# `follows` 是 inputs 中的继承语法
|
|
||||||
# 这里使 sops-nix 的 `inputs.nixpkgs` 与当前 flake 的 inputs.nixpkgs 保持一致,
|
|
||||||
# 避免依赖的 nixpkgs 版本不一致导致问题
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
|
|
||||||
# 将 flake 锁定在某个 commit 上
|
|
||||||
nix-doom-emacs = {
|
|
||||||
url = "github:vlaci/nix-doom-emacs?rev=238b18d7b2c8239f676358634bfb32693d3706f3";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# 使用 `dir` 参数指定某个子目录
|
|
||||||
nixpkgs.url = "github:foo/bar?dir=shu";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Flake 的 outputs {#flake-outputs}
|
|
||||||
|
|
||||||
`flake.nix` 中的 `outputs` 是一个 attribute set,是整个 Flake 的构建结果,每个 Flake 都可以有许多不同的 outputs。
|
|
||||||
|
|
||||||
一些特定名称的 outputs 有特殊用途,会被某些 Nix 命令识别处理,比如:
|
|
||||||
|
|
||||||
- Nix packages: 名称为 `apps.<system>.<name>`, `packages.<system>.<name>` 或 `legacyPackages.<system>.<name>` 的 outputs,都是 Nix 包,通常都是一个个应用程序。
|
|
||||||
- 可以通过 `nix build .#name` 来构建某个 nix 包
|
|
||||||
- Nix Helper Functions: 名称为 `lib` 的 outputs 是 Flake 函数库,可以被其他 Flake 作为 inputs 导入使用。
|
|
||||||
- Nix development environments: 名称为 `devShells` 的 outputs 是 Nix 开发环境
|
|
||||||
- 可以通过 `nix develop` 命令来使用该 Output 创建开发环境
|
|
||||||
- NixOS configurations: 名称为 `nixosConfigurations.<hostname>` 的 outputs,是 NixOS 的系统配置。
|
|
||||||
- `nixos-rebuild switch .#<hostname>` 可以使用该 Output 来部署 NixOS 系统
|
|
||||||
- Nix templates: 名称为 `templates` 的 outputs 是 flake 模板
|
|
||||||
- 可以通过执行命令 `nix flake init --template <reference>` 使用模板初始化一个 Flake 包
|
|
||||||
- 其他用户自定义的 outputs,可能被其他 Nix 相关的工具使用
|
|
||||||
|
|
||||||
NixOS Wiki 中给出的使用案例:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
{ self, ... }@inputs:
|
|
||||||
{
|
|
||||||
# Executed by `nix flake check`
|
|
||||||
checks."<system>"."<name>" = derivation;
|
|
||||||
# Executed by `nix build .#<name>`
|
|
||||||
packages."<system>"."<name>" = derivation;
|
|
||||||
# Executed by `nix build .`
|
|
||||||
packages."<system>".default = derivation;
|
|
||||||
# Executed by `nix run .#<name>`
|
|
||||||
apps."<system>"."<name>" = {
|
|
||||||
type = "app";
|
|
||||||
program = "<store-path>";
|
|
||||||
};
|
|
||||||
# Executed by `nix run . -- <args?>`
|
|
||||||
apps."<system>".default = { type = "app"; program = "..."; };
|
|
||||||
|
|
||||||
# Formatter (alejandra, nixfmt or nixpkgs-fmt)
|
|
||||||
formatter."<system>" = derivation;
|
|
||||||
# Used for nixpkgs packages, also accessible via `nix build .#<name>`
|
|
||||||
legacyPackages."<system>"."<name>" = derivation;
|
|
||||||
# Overlay, consumed by other flakes
|
|
||||||
overlays."<name>" = final: prev: { };
|
|
||||||
# Default overlay
|
|
||||||
overlays.default = {};
|
|
||||||
# Nixos module, consumed by other flakes
|
|
||||||
nixosModules."<name>" = { config }: { options = {}; config = {}; };
|
|
||||||
# Default module
|
|
||||||
nixosModules.default = {};
|
|
||||||
# Used with `nixos-rebuild --flake .#<hostname>`
|
|
||||||
# nixosConfigurations."<hostname>".config.system.build.toplevel must be a derivation
|
|
||||||
nixosConfigurations."<hostname>" = {};
|
|
||||||
# Used by `nix develop .#<name>`
|
|
||||||
devShells."<system>"."<name>" = derivation;
|
|
||||||
# Used by `nix develop`
|
|
||||||
devShells."<system>".default = derivation;
|
|
||||||
# Hydra build jobs
|
|
||||||
hydraJobs."<attr>"."<system>" = derivation;
|
|
||||||
# Used by `nix flake init -t <flake>#<name>`
|
|
||||||
templates."<name>" = {
|
|
||||||
path = "<store-path>";
|
|
||||||
description = "template description goes here?";
|
|
||||||
};
|
|
||||||
# Used by `nix flake init -t <flake>`
|
|
||||||
templates.default = { path = "<store-path>"; description = ""; };
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Flake 命令行的使用 {#flake-commands-usage}
|
|
||||||
|
|
||||||
在启用了 `nix-command` & `flakes` 功能后,我们就可以使用 Nix 提供的新一代 Nix 命令行工具 [New Nix Commands][New Nix Commands] 了,下面列举下其中常用命令的用法:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 解释下这条指令涉及的参数:
|
|
||||||
# `nixpkgs#ponysay` 意思是 `nixpkgs` 这个 flake 中的 `ponysay` 包。
|
|
||||||
# `nixpkgs` 是一个 flakeregistry ida,
|
|
||||||
# nix 会从 <https://github.com/NixOS/flake-registry/blob/master/flake-registry.json> 中
|
|
||||||
# 找到这个 id 对应的 github 仓库地址
|
|
||||||
# 所以这个命令的意思是创建一个新环境,安装并运行 `nixpkgs` 这个 flake 提供的 `ponysay` 包。
|
|
||||||
# 注:前面已经介绍过了,nix 包 是 flake outputs 中的一种。
|
|
||||||
echo "Hello Nix" | nix run "nixpkgs#ponysay"
|
|
||||||
|
|
||||||
# 这条命令和上面的命令作用是一样的,只是使用了完整的 flake URI,而不是 flakeregistry id。
|
|
||||||
echo "Hello Nix" | nix run "github:NixOS/nixpkgs/nixos-unstable#ponysay"
|
|
||||||
|
|
||||||
# 这条命令的作用是使用 zero-to-nix 这个 flake 中名 `devShells.example` 的 outptus 来创建一个开发环境,
|
|
||||||
# 然后在这个环境中打开一个 bash shell。
|
|
||||||
nix develop "github:DeterminateSystems/zero-to-nix#example"
|
|
||||||
|
|
||||||
# 除了使用远程 flake uri 之外,你也可以使用当前目录下的 flake 来创建一个开发环境。
|
|
||||||
mkdir my-flake && cd my-flake
|
|
||||||
## 通过模板初始化一个 flake
|
|
||||||
nix flake init --template "github:DeterminateSystems/zero-to-nix#javascript-dev"
|
|
||||||
## 使用当前目录下的 flake 创建一个开发环境,并打开一个 bash shell
|
|
||||||
nix develop
|
|
||||||
# 或者如果你的 flake 有多个 devShell 输出,你可以指定使用名为 example 的那个
|
|
||||||
nix develop .#example
|
|
||||||
|
|
||||||
# 构建 `nixpkgs` flake 中的 `bat` 这个包
|
|
||||||
# 并在当前目录下创建一个名为 `result` 的符号链接,链接到该构建结果文件夹。
|
|
||||||
mkdir build-nix-package && cd build-nix-package
|
|
||||||
nix build "nixpkgs#bat"
|
|
||||||
# 构建一个本地 flake 和 nix develop 是一样的,不再赘述
|
|
||||||
```
|
|
||||||
|
|
||||||
此外 [Zero to Nix - Determinate Systems][Zero to Nix - Determinate Systems] 是一份全新的 Nix & Flake 新手入门文档,写得比较浅显易懂,适合新手用来入门。
|
|
41
docs/zh/flakes/inputs.md
Normal file
41
docs/zh/flakes/inputs.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
### 1. Flake 的 inputs {#flake-inputs}
|
||||||
|
|
||||||
|
`flake.nix` 中的 `inputs` 是一个 attribute set,用来指定当前 Flake 的依赖,inputs 有很多种类型,举例如下:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
# 以 GitHub 仓库为数据源,指定使用 master 分支,这是最常见的 input 格式
|
||||||
|
nixpkgs.url = "github:Mic92/nixpkgs/master";
|
||||||
|
# Git URL,可用于任何基于 https/ssh 协议的 Git 仓库
|
||||||
|
git-example.url = "git+https://git.somehost.tld/user/path?ref=branch&rev=fdc8ef970de2b4634e1b3dca296e1ed918459a9e";
|
||||||
|
# 上面的例子会复制 .git 到本地, 如果数据量较大,建议使用 shallow=1 参数避免复制 .git
|
||||||
|
git-directory-example.url = "git+file:/path/to/repo?shallow=1";
|
||||||
|
# 本地文件夹 (如果使用绝对路径,可省略掉前缀 'path:')
|
||||||
|
directory-example.url = "path:/path/to/repo";
|
||||||
|
# 如果数据源不是一个 flake,则需要设置 flake=false
|
||||||
|
bar = {
|
||||||
|
url = "github:foo/bar/branch";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
sops-nix = {
|
||||||
|
url = "github:Mic92/sops-nix";
|
||||||
|
# `follows` 是 inputs 中的继承语法
|
||||||
|
# 这里使 sops-nix 的 `inputs.nixpkgs` 与当前 flake 的 inputs.nixpkgs 保持一致,
|
||||||
|
# 避免依赖的 nixpkgs 版本不一致导致问题
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
|
# 将 flake 锁定在某个 commit 上
|
||||||
|
nix-doom-emacs = {
|
||||||
|
url = "github:vlaci/nix-doom-emacs?rev=238b18d7b2c8239f676358634bfb32693d3706f3";
|
||||||
|
flake = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# 使用 `dir` 参数指定某个子目录
|
||||||
|
nixpkgs.url = "github:foo/bar?dir=shu";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
6
docs/zh/flakes/intro.md
Normal file
6
docs/zh/flakes/intro.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
## 七、Nix Flakes 的使用 {#nix-flakes-usage}
|
||||||
|
|
||||||
|
到这里我们已经写了不少 Nix Flakes 配置来管理 NixOS 系统了,这里再简单介绍下 Nix Flakes 更细节的内容,以及常用的 nix flake 命令。
|
||||||
|
|
||||||
|
此外 [Zero to Nix - Determinate Systems][Zero to Nix - Determinate Systems] 是一份全新的 Nix & Flake 新手入门文档,写得比较浅显易懂,也可以一读。
|
68
docs/zh/flakes/outputs.md
Normal file
68
docs/zh/flakes/outputs.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
|
||||||
|
|
||||||
|
### 2. Flake 的 outputs {#flake-outputs}
|
||||||
|
|
||||||
|
`flake.nix` 中的 `outputs` 是一个 attribute set,是整个 Flake 的构建结果,每个 Flake 都可以有许多不同的 outputs。
|
||||||
|
|
||||||
|
一些特定名称的 outputs 有特殊用途,会被某些 Nix 命令识别处理,比如:
|
||||||
|
|
||||||
|
- Nix packages: 名称为 `apps.<system>.<name>`, `packages.<system>.<name>` 或 `legacyPackages.<system>.<name>` 的 outputs,都是 Nix 包,通常都是一个个应用程序。
|
||||||
|
- 可以通过 `nix build .#name` 来构建某个 nix 包
|
||||||
|
- Nix Helper Functions: 名称为 `lib` 的 outputs 是 Flake 函数库,可以被其他 Flake 作为 inputs 导入使用。
|
||||||
|
- Nix development environments: 名称为 `devShells` 的 outputs 是 Nix 开发环境
|
||||||
|
- 可以通过 `nix develop` 命令来使用该 Output 创建开发环境
|
||||||
|
- NixOS configurations: 名称为 `nixosConfigurations.<hostname>` 的 outputs,是 NixOS 的系统配置。
|
||||||
|
- `nixos-rebuild switch .#<hostname>` 可以使用该 Output 来部署 NixOS 系统
|
||||||
|
- Nix templates: 名称为 `templates` 的 outputs 是 flake 模板
|
||||||
|
- 可以通过执行命令 `nix flake init --template <reference>` 使用模板初始化一个 Flake 包
|
||||||
|
- 其他用户自定义的 outputs,可能被其他 Nix 相关的工具使用
|
||||||
|
|
||||||
|
NixOS Wiki 中给出的使用案例:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{ self, ... }@inputs:
|
||||||
|
{
|
||||||
|
# Executed by `nix flake check`
|
||||||
|
checks."<system>"."<name>" = derivation;
|
||||||
|
# Executed by `nix build .#<name>`
|
||||||
|
packages."<system>"."<name>" = derivation;
|
||||||
|
# Executed by `nix build .`
|
||||||
|
packages."<system>".default = derivation;
|
||||||
|
# Executed by `nix run .#<name>`
|
||||||
|
apps."<system>"."<name>" = {
|
||||||
|
type = "app";
|
||||||
|
program = "<store-path>";
|
||||||
|
};
|
||||||
|
# Executed by `nix run . -- <args?>`
|
||||||
|
apps."<system>".default = { type = "app"; program = "..."; };
|
||||||
|
|
||||||
|
# Formatter (alejandra, nixfmt or nixpkgs-fmt)
|
||||||
|
formatter."<system>" = derivation;
|
||||||
|
# Used for nixpkgs packages, also accessible via `nix build .#<name>`
|
||||||
|
legacyPackages."<system>"."<name>" = derivation;
|
||||||
|
# Overlay, consumed by other flakes
|
||||||
|
overlays."<name>" = final: prev: { };
|
||||||
|
# Default overlay
|
||||||
|
overlays.default = {};
|
||||||
|
# Nixos module, consumed by other flakes
|
||||||
|
nixosModules."<name>" = { config }: { options = {}; config = {}; };
|
||||||
|
# Default module
|
||||||
|
nixosModules.default = {};
|
||||||
|
# Used with `nixos-rebuild --flake .#<hostname>`
|
||||||
|
# nixosConfigurations."<hostname>".config.system.build.toplevel must be a derivation
|
||||||
|
nixosConfigurations."<hostname>" = {};
|
||||||
|
# Used by `nix develop .#<name>`
|
||||||
|
devShells."<system>"."<name>" = derivation;
|
||||||
|
# Used by `nix develop`
|
||||||
|
devShells."<system>".default = derivation;
|
||||||
|
# Hydra build jobs
|
||||||
|
hydraJobs."<attr>"."<system>" = derivation;
|
||||||
|
# Used by `nix flake init -t <flake>#<name>`
|
||||||
|
templates."<name>" = {
|
||||||
|
path = "<store-path>";
|
||||||
|
description = "template description goes here?";
|
||||||
|
};
|
||||||
|
# Used by `nix flake init -t <flake>`
|
||||||
|
templates.default = { path = "<store-path>"; description = ""; };
|
||||||
|
}
|
||||||
|
```
|
37
docs/zh/flakes/the-new-cli.md
Normal file
37
docs/zh/flakes/the-new-cli.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
### 3. Flake 命令行的使用 {#flake-commands-usage}
|
||||||
|
|
||||||
|
在启用了 `nix-command` & `flakes` 功能后,我们就可以使用 Nix 提供的新一代 Nix 命令行工具 [New Nix Commands][New Nix Commands] 了,下面列举下其中常用命令的用法:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 解释下这条指令涉及的参数:
|
||||||
|
# `nixpkgs#ponysay` 意思是 `nixpkgs` 这个 flake 中的 `ponysay` 包。
|
||||||
|
# `nixpkgs` 是一个 flakeregistry ida,
|
||||||
|
# nix 会从 <https://github.com/NixOS/flake-registry/blob/master/flake-registry.json> 中
|
||||||
|
# 找到这个 id 对应的 github 仓库地址
|
||||||
|
# 所以这个命令的意思是创建一个新环境,安装并运行 `nixpkgs` 这个 flake 提供的 `ponysay` 包。
|
||||||
|
# 注:前面已经介绍过了,nix 包 是 flake outputs 中的一种。
|
||||||
|
echo "Hello Nix" | nix run "nixpkgs#ponysay"
|
||||||
|
|
||||||
|
# 这条命令和上面的命令作用是一样的,只是使用了完整的 flake URI,而不是 flakeregistry id。
|
||||||
|
echo "Hello Nix" | nix run "github:NixOS/nixpkgs/nixos-unstable#ponysay"
|
||||||
|
|
||||||
|
# 这条命令的作用是使用 zero-to-nix 这个 flake 中名 `devShells.example` 的 outptus 来创建一个开发环境,
|
||||||
|
# 然后在这个环境中打开一个 bash shell。
|
||||||
|
nix develop "github:DeterminateSystems/zero-to-nix#example"
|
||||||
|
|
||||||
|
# 除了使用远程 flake uri 之外,你也可以使用当前目录下的 flake 来创建一个开发环境。
|
||||||
|
mkdir my-flake && cd my-flake
|
||||||
|
## 通过模板初始化一个 flake
|
||||||
|
nix flake init --template "github:DeterminateSystems/zero-to-nix#javascript-dev"
|
||||||
|
## 使用当前目录下的 flake 创建一个开发环境,并打开一个 bash shell
|
||||||
|
nix develop
|
||||||
|
# 或者如果你的 flake 有多个 devShell 输出,你可以指定使用名为 example 的那个
|
||||||
|
nix develop .#example
|
||||||
|
|
||||||
|
# 构建 `nixpkgs` flake 中的 `bat` 这个包
|
||||||
|
# 并在当前目录下创建一个名为 `result` 的符号链接,链接到该构建结果文件夹。
|
||||||
|
mkdir build-nix-package && cd build-nix-package
|
||||||
|
nix build "nixpkgs#bat"
|
||||||
|
# 构建一个本地 flake 和 nix develop 是一样的,不再赘述
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user