保留 NixOS 25.05 的历史问题范围,并以当前官方模块校正配置接口。实际使用前检查项目锁定的 nixpkgs、Home Manager 和 quadlet-nix revision;本篇没有评估或激活任何系统。
路径选择:三条路#
NixOS 上管理 Podman 有三条路径,复杂度递增:
graph TD
A["想在 NixOS 上用 Podman"] --> B{"如何管理容器?"}
B -->|"临时运行"| C["virtualisation.podman<br/>系统级配置"]
B -->|"持久服务"| D{"偏好哪种配置方式?"}
D -->|"Home Manager"| E["services.podman<br/>Home Manager 模块"]
D -->|"纯 Nix 声明式"| F["quadlet-nix<br/>第三方 Flake"]路径一:系统级 Podman(最简单)#
直接加到 configuration.nix:
{ config, pkgs, ... }:
{
# 启用容器支持
virtualisation.containers.enable = true;
virtualisation.podman = {
enable = true;
# Docker CLI 兼容(创建 docker → podman 软链接)
dockerCompat = true;
# DNS 解析
defaultNetwork.settings.dns_enabled = true;
};
}# 配置完成后先评估/构建;是否激活由管理员单独决定
nix flake check --no-build
nixos-rebuild dry-build --flake .#workstation
# 激活后的独立检查
podman --version系统模块启用 Podman 并不强制 rootful:普通用户可 rootless 运行,是否需要 sudo 取决于目标工作流。podman 组不是 rootless 前提;启用系统 Docker-compatible socket 时,其组访问可能赋予 root 级管理能力,不能随意添加。
路径二:Home Manager Rootless Podman(推荐)#
2.1 系统级先启用 Podman
# configuration.nix
{
virtualisation.containers.enable = true;
virtualisation.podman.enable = true;
virtualisation.podman.dockerCompat = true;
virtualisation.podman.defaultNetwork.settings.dns_enabled = true;
# 不全局重写用户PATH;由所用模块/生成unit提供程序及newuidmap等依赖
}2.2 用户设置
# 在 users.users 中
users.users.user = {
isNormalUser = true;
linger = true; # ← 关键!允许用户服务在登录前启动
# subUidRanges/subGidRanges — 为用户分配 UID 范围(rootless 的前提)
subUidRanges = [{ startUid = 100000; count = 65536; }];
subGidRanges = [{ startGid = 100000; count = 65536; }];
};2.3 Home Manager 配置
# home.nix 或 home-manager 模块
{ pkgs, ... }: {
services.podman = {
enable = true;
# 启用自动更新定时器
autoUpdate.enable = true;
};
# 声明式网络
services.podman.networks = {
webnet = {
driver = "bridge";
subnet = "192.0.2.0/24"; # 文档示例;实际选不冲突的容器网段
};
};
}# standalone Home Manager先build;NixOS集成模式随系统配置构建
home-manager build
# 经授权激活后另查运行时timer
systemctl --user status podman-auto-update.timer2.4 声明式容器
services.podman.containers = {
myweb = {
image = "docker.io/library/nginx:alpine";
autoStart = true;
autoUpdate = "registry";
ports = [ "127.0.0.1:8080:80" ];
volumes = [
"/path/to/dedicated-data:/usr/share/nginx/html:ro,Z"
];
environment = {
MYVAR = "hello";
};
};
};路径三:quadlet-nix(先进,原生 Quadlet)#
quadlet-nix 是一个 Nix Flake,把 Podman 的 Quadlet 功能映射为 Nix 声明式语法。
基本用法
# flake.nix:standalone Home Manager示例;不是nixosSystem构造homeConfigurations
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager.url = "github:nix-community/home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
quadlet-nix.url = "github:SEIAROTg/quadlet-nix";
};
outputs = { nixpkgs, home-manager, quadlet-nix, ... }: {
homeConfigurations.user = home-manager.lib.homeManagerConfiguration {
pkgs = import nixpkgs { system = "x86_64-linux"; };
modules = [
quadlet-nix.homeManagerModules.quadlet
({ config, ... }: {
home.username = "user";
home.homeDirectory = "/home/user";
home.stateVersion = "25.05"; # 使用账户实际首次配置版本,不随升级随意改
virtualisation.quadlet = {
containers.echo-server = {
autoStart = true;
containerConfig = {
image = "docker.io/mendhak/http-https-echo:31";
publishPorts = [ "127.0.0.1:8080:8080" ];
userns = "keep-id";
networks = [ config.virtualisation.quadlet.networks.mynet.ref ];
};
};
networks.mynet.networkConfig.driver = "bridge";
volumes.mydata = { };
};
})
];
};
};
}效果:quadlet-nix 自动生成对应的 .container/.network/.volume Quadlet 文件,由 systemd 管理。
NixOS 25.05 已知问题#
oci-containers + podman.user 有 bug
NixOS 25.05 的 virtualisation.oci-containers.containers.<name>.podman.user 功能有已知问题(nixpkgs #410857):
- systemd 服务可能报
Failed with result 'protocol' - 部分场景下容器仍以 root 运行
该问题是 25.05 版本/场景的历史记录,不能推出当前所有 oci-containers rootless 都失效。先对照锁定分支的实现与问题状态;需要用户级管理时可评估 Home Manager 或 quadlet-nix,保留已有方案和恢复路径。
卷权限问题
Rootless 容器挂载卷时,目录所有权可能出现问题:
# 先核对容器应用UID映射和宿主目录权限
# 可用Home Manager的systemd.user.tmpfiles.rules管理专用目录,但不替代UID映射核对快速对照表#
| 需求 | 用哪个路径 |
|---|---|
| 快速跑一次容器 | podman run(装了就行) |
| 开发环境 | 路径一 + podman-compose |
| 稳定 rootless 容器服务 | 路径二(Home Manager services.podman) |
| 纯 Nix 声明式 + Quadlet 全功能 | 路径三(quadlet-nix) |
| 已经在用 Docker Compose | 保持 compose 文件,用 podman-compose |
系统启用模块、Home Manager配置生成、构建、激活与实际容器行为是不同验证层。示例假定宿主已提供 user namespace/newuidmap 条件;独立 Home Manager不能替代所有系统前置。subUID/GID范围须检查冲突,已有存储迁移不要直接换范围;linger只在需登录前运行时设置。当前 Home Manager Podman模块可生成Quadlet资源,因此不要把“Home Manager”与“Quadlet”当作永远互斥的架构。生成服务名以实际产物为准。以上没有自动执行switch或容器部署。
当前上游 Home Manager 的 autoUpdate 服务还会在更新后执行 image prune -f;启用前检查锁定版本生成的 ExecStart/ExecStartPost、定时周期和镜像保留需求。
参考与延伸
- Podman 官方 run 手册 ↗
- Podman 官方总览与 rootless ↗
- NixOS 25.05 Podman模块 ↗
- Home Manager Podman模块 ↗
- quadlet-nix 官方说明 ↗
- NixOS 25.05历史问题 ↗
根据技术笔记重新整理,示例使用通用名称。