OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 125

NixOS 上的 Podman 管理

通过系统模块、Home Manager 或 quadlet-nix 声明容器运行环境。

所在专题Podman 容器工作流 ↗
约 12 分钟阅读开始阅读

保留 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.timer

2.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、定时周期和镜像保留需求。

参考与延伸

  1. Podman 官方 run 手册 ↗
  2. Podman 官方总览与 rootless ↗
  3. NixOS 25.05 Podman模块 ↗
  4. Home Manager Podman模块 ↗
  5. quadlet-nix 官方说明 ↗
  6. NixOS 25.05历史问题 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Podman 容器工作流

  1. 01Podman 基础原理
  2. 02Podman 基本使用指南
  3. 03Rootless 容器,文件权限到底算谁的?
  4. 04Rootless 配置:映射、ICMP 与注册表
  5. 05Pod 体系与 Kubernetes 清单
  6. 06Quadlet 如何把容器声明变成服务?
  7. 07Quadlet 的 Pod 与多服务配置
  8. 08Compose provider 与 Docker 工具互操作
  9. 09NixOS 上的 Podman 管理
  10. 10Podman 高级运维与调优
  11. 11Docker 与 Podman:架构、兼容与共存
CONTINUE READING / 下一篇Podman 高级运维与调优

管理资源、健康状态、镜像工具链、日志与存储清理。