在 NixOS 上运行一个简单的 Go Web 服务

作者有一些 24/7 在云基础设施上运行的玩具实用应用程序,如PicoShare。虽有一些便利应用想 24/7 运行但因摩擦大未实现。过去在家庭服务器上尝试过,虽设置了 cron 任务和 systemd 服务,但总会出问题,最终放弃。

作者最终找到一种低摩擦的方式来托管个人应用,即 NixOS 模块:

  • 能做的事:运行任意 Web 服务 24/7 只需不到 15 分钟;可通过改代码和运行重建命令升级/降级或更改配置选项;可在同一服务器上运行有冲突依赖的应用且不用担心版本冲突;可将整个服务器配置置于源代码控制下以便随时回滚。
  • 为何选择 NixOS:全系统配置在文本文件中;重建系统相对较快(通常数秒或数分钟);服务便于组合和扩展。
  • Nix 不复杂:过去一年在学习 Nix 的一些技巧,可在不理解全部内容的情况下学会有用的技术,如用于设置项目开发环境,认为 NixOS 模块处于中等难度,看过示例后容易复制。
  • 为何不选 Ansible:曾认为 Ansible 是 24/7 运行服务的好方案,但 Ansible 运行慢,每次添加新服务到服务器需更长时间,且易出现版本冲突,如一个服务依赖 Python2,另一个依赖 Python3.7 和 Python3.10 会相互冲突。
  • 为何不选 Docker:在 Docker 下运行服务可行,但对开发不友好,在 NixOS 和 Ansible 中可大部分复用打包代码,在 Docker 容器内进行开发不是 Docker 设计的目的,会与工具冲突,且当有多个运行进程时 Docker 更难使用,如 Web 应用依赖 Postgres 时需两个 Docker 容器,管理更复杂,虽见过 Podman、Rancher 和 k3s 等解决方案但未使用,它们似乎更复杂。

NixOS 要求:需要启用 flakes 的 NixOS 系统,作者使用 NixOS 24.05,并写了在 Raspberry Pi 4 和 Proxmox 下安装 NixOS 的教程。

基本演示微服务:创建main.go文件定义简单 Go Web 服务,可通过nix-shell -p go --command 'PORT=5000 go run main.go'运行服务,也可在浏览器中查看,该服务旨在专注于 NixOS 打包部分。

创建 Go 模块:nix-shell -p go --command 'go mod init codeberg.org/mtlynch/basic-go-web-app'创建go.mod文件。

创建基本 Nix flake:在flake.nix文件中定义 Nix flake 来构建和运行应用,可通过PORT=5000 nix run运行应用,注意 flake 版本和nix-shell版本的 Go 版本不同。

添加 NixOS 模块到 Nix flake:调整flake.nix定义 NixOS 模块,包括定义模块选项(如enableport)、定义 systemd 配置(如ExecStartRestart等)、导出 NixOS 模块,使服务可在后台自动运行。

安装 NixOS 模块:将basic-go-web-appNixOS 模块导入到 NixOS 系统的根flake.nix文件中,在主机的 Nix 文件中配置服务相关选项,然后重建主机,服务成功运行,现在运行在basic-go-web-app用户下而非开发者mike用户下。

源代码:完整源代码在 Codeberg 上,链接为https://codeberg.org/mtlynch/basic-go-web-app

结论:展示的 Web 应用简单,但作者有类似复杂度的实用工具,难点是找到一种无需额外打包或维护工作即可 24/7 运行服务的方式,刚开始使用 NixOS 模块管理个人服务,对其效果很兴奋。

阅读 7
0 条评论