如何用nix-build和dockerTools.buildImage构建Podman兼容容器?
Nix构建兼容Podman的容器镜像问题及解决方法
问题描述
使用nix-build构建包含Bash、Busybox和Invidious的容器镜像时,Docker可正常加载,但Podman加载时报错。
原构建文件invidious.nix
let # nixos-22.05 / https://status.nixos.org/ pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {}; in rec { docker = pkgs.dockerTools.buildImage { name = "invidious"; contents = [ pkgs.busybox pkgs.bash pkgs.invidious ]; config = { Cmd = [ "/bin/bash" ]; Env = []; Volumes = {}; }; }; }
Docker加载正常
执行命令:
docker load < result
输出:
14508d34fd29: Loading layer [==================================================>] 156.6MB/156.6MB Loaded image: invidious:2nrcdxgz46isccfgyzdcbirs0vvqhp55
Podman加载报错
执行命令:
podman load < result
错误输出:
Error: payload does not match any of the supported image formats: * oci: initializing source oci:/var/tmp/podman3824611648:: open /var/tmp/podman3824611648/index.json: not a directory * oci-archive: loading index: open /var/tmp/oci1927542201/index.json: no such file or directory * docker-archive: loading tar component manifest.json: archive/tar: invalid tar header * dir: open /var/tmp/podman3824611648/manifest.json: not a directory
镜像文件结构
执行tar tvfz result查看结构:
dr-xr-xr-x root/root 0 1979-12-31 19:00 ./ -r--r--r-- root/root 391 1979-12-31 19:00 027302622543ef251be6d3f2d616f98c73399d8cd074b0d1497e5a7da5e6c882.json dr-xr-xr-x root/root 0 1979-12-31 19:00 669db3729b40e36a9153569b747788611e547f0b50a9f7d77107a04c6ddd887e/ -r--r--r-- root/root 3 1979-12-31 19:00 669db3729b40e36a9153569b747788611e547f0b50a9f7d77107a04c6ddd887e/VERSION -r--r--r-- root/root 353 1979-12-31 19:00 669db3729b40e36a9153569b747788611e547f0b50a9f7d77107a04c6ddd887e/json -r--r--r-- root/root 156579840 1979-12-31 19:00 669db3729b40e36a9153569b747788611e547f0b50a9f7d77107a04c6ddd887e/layer.tar -r--r--r-- root/root 280 1979-12-31 19:00 manifest.json -r--r--r-- root/root 128 1979-12-31 19:00 repositories
解决方案
方法1:构建标准OCI格式镜像
将dockerTools.buildImage替换为dockerTools.buildOCIImage,生成Podman原生支持的OCI格式镜像:
修改后的invidious.nix:
let # nixos-22.05 / https://status.nixos.org/ pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {}; in rec { oci-image = pkgs.dockerTools.buildOCIImage { name = "invidious"; contents = [ pkgs.busybox pkgs.bash pkgs.invidious ]; config = { Cmd = [ "/bin/bash" ]; Env = []; Volumes = {}; }; }; }
构建后执行podman load < result即可正常加载。
方法2:构建分层镜像(兼容Docker和Podman)
使用dockerTools.buildLayeredImage替代buildImage,生成符合规范的docker-archive格式镜像,同时兼容Docker和Podman:
let # nixos-22.05 / https://status.nixos.org/ pkgs = import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/d86a4619b7e80bddb6c01bc01a954f368c56d1df.tar.gz") {}; in rec { docker = pkgs.dockerTools.buildLayeredImage { name = "invidious"; contents = [ pkgs.busybox pkgs.bash pkgs.invidious ]; config = { Cmd = [ "/bin/bash" ]; Env = []; Volumes = {}; }; }; }
原因说明
原dockerTools.buildImage生成的是Docker专属的简化tar格式,未严格遵循标准镜像格式规范,导致Podman无法识别。而buildOCIImage生成标准OCI镜像格式,buildLayeredImage生成符合docker-archive规范的镜像,两者都能通过Podman的格式校验。
内容的提问来源于stack exchange,提问作者djsumdog
相关产品推荐
相关产品推荐

