背景
在春节假期时,无意中浏览到了 ryan4yin 的博客,初次见识到了这个系统。我们早已习惯在 /etc 目录下与无数配置文件搏斗,在软件版本依赖的地狱中挣扎。当系统升级导致开发环境崩溃时,那种熟悉的恐惧感总会涌上心头。Docker 容器虽然提供了临时避难所,却始终治标不治本。
NixOS 让人强烈欲望入坑的特点
- 用一份
/etc/nixos/configuration.nix
文件定义整个系统 - 每次系统配置更新,都会提供 Generation 防止错误配置无法回退
- 完全可复现的开发环境,只需要
git clone
,不再需要pacman
或apt
万物之始
我们可以从 NixOS 官方下载 Minimal ISO image,在一台全新的机器上安装 NixOS。或是通过 nixos-infect 脚本,一键将非 NixOS 的系统转换成 NixOS。后者在阿里云 ECS 上测试是可用的。
非常非常 Easy 的配置文件
/etc/nixos/configuration.nix
,在下面的配置中,我们指定了
root 用户的 authorizedKeys 以及密码,配置了 ssh-server,配置了
vscode-server,主机名等信息都可以通过该配置文件完成。当把下面的文件写入后,只需要运行
nixos-rebuild switch
,一切都完成了。
我的服务器通过手动划分磁盘,挂载 btrfs 后,执行
nixos-install
脚本安装。更详细的安装教程可以参考这篇博客:从 0 实现全集梦中情
OS。如果对于操作没有那么熟悉,可以现在虚拟机中尝试,后续想部署到服务器上,只需要复制配置文件到服务器,执行
nixos-rebuild switch
,就都一模一样了。
1 | # Edit this configuration file to define what should be installed on |
开发环境配置(Devbox 与 Direnv)
在软件开发中,环境配置一直是令人头疼的难题。不同项目对编译器版本、依赖库、环境变量的差异化需求,常常导致"在我的机器上能运行"的经典问题。接下来将介绍基于 Devbox 和 Direnv 管理环境方案,通过两个典型 Go 项目案例,展示如何实现开发环境的精准控制。
准备事项
在所有例子之前,必须安装 devbox 和 direnv,同时给 IDE 装上支持 direnv
的插件。如果使用的是 NixOS,添加如下配置文件,并
nixos-rebuild switch
。
1 | programs.direnv.enable = true; |
例子一:杂交的 Go 程序,开启 CGO 与 [email protected] 版本
需要编译使用 CGO 的 Go 程序,并链接 RocksDB v9.8.4 数据库。该场景的复杂性在于:
- 必须启用 CGO 支持
- 需要特定版本的 C 库(RocksDB)
- 依赖 pkg-config 查找头文件路径
首先进入项目的根目录,执行:
1 | # 初始化 Devbox 项目 |
此时打开 shell,输入 pkg-config --cflags --libs rocksdb
所有环境都已经配置好了,就这么简单。
1 | $ pkg-config --cflags --libs rocksdb |
例子二:老旧的 Go 程序,必须使用 [email protected] 版本
首先进入项目的根目录,执行:
1 | devbox init |
此时打开 shell,执行以下步骤即可验证:
1 | # 在项目目录内验证 |
更多杂项配置
TODO
Nixpkg 相关资料
- https://search.nixos.org/options
搜索
/etc/nixos/configuration.nix
文件的配置写法,例如安装 docker,根据它的描述,只需要添加一行即可:virtualisation.docker.enable = true;
- https://search.nixos.org/packages 相关 nixpkgs 的搜索,只要包不是离奇的冷门,都能找到,不过找不到旧版本的包。比如说 Go 的 1.20 版本无法在 24.11 里找到。
- https://www.nixhub.io/ Devbox 的相关网站,可以找到最新的包和历史所有包。例如 Go 的 1.20 版本在这里。
Devbox 常用命令
devbox init
: 为项目初始化 devbox, 运行后项目目录下会出现devbox.json
文件,可以直接在文件中添加要使用的软件包,也可以像 npm 之类的包管理器一样使用devbox add
添加软件包。devbox add
: 添加软件包,后面可以跟有 @xxx 指定版本号,如devbox add [email protected]
。dev search
: 搜索软件包dev rm
: 删除软件包devbox generate direnv
: 自动为 direnv 生成.envrc
文件,安装配置好后会自动载入环境。devbox shell
: 手动进入环境终端devbox run
: 手动运行命令(在devbox.json
中shell.scripts
字段下手动添加script
,类似 node 的package.json
中的 scripts)