2016 年精彩的博客文章描述了使用 Nix 构建最小的 Docker 镜像。下面是摘自该博客文章的一个简单示例,经过修改以支持 Nix 2.0:
{ pkgs ? import <nixpkgs> {} }:
with pkgs;
dockerTools.buildImage {
name = "redis";
runAsRoot = ''
#!${stdenv.shell}
${dockerTools.shadowSetup}
groupadd -r redis
useradd -r -g redis -d /data -M redis
mkdir /data
chown redis:redis /data
'';
config = {
Cmd = [ "${gosu.bin}/bin/gosu" "redis" "${redis}/bin/redis-server" ];
ExposedPorts = {
"6379/tcp" = {};
};
WorkingDir = "/data";
Volumes = {
"/data" = {};
};
};
}
使用nix-linuxkit
bash
要拥有 x86_64-linux 构建器,此操作会失败,并出现有关无法运行的可执行文件的错误:
$ nix-build -j 1 --system x86_64-linux redis-small.nix
these derivations will be built:
/nix/store/iixmgfhsczc71484vcwqwz2nzlg0rcv1-extra-commands.sh.drv
/nix/store/jsydsrzs7h9pfnh8m6cxaysa9bafmp2z-redis-config.json.drv
/nix/store/csfmyw6va3b8dabshliqjkrrdr6n090w-vm-run-stage2.drv
/nix/store/l0p201r6zjfzsznfb6ykca1l8n09lyb9-vm-run.drv
/nix/store/s64kqfyggqm60l5j9wy6s1nz39iwkxiw-run-as-root.sh.drv
/nix/store/zidg0xphc7yjc4n0w3k7wnifz6rlqgzh-docker-layer-redis.drv
/nix/store/12ahsincv8igv492gzjjvw9s8aaff65i-runtime-deps.drv
/nix/store/pyx4q2wln2shlnjdp5ng43aqd6iba80d-docker-image-redis.tar.gz.drv
building '/nix/store/jsydsrzs7h9pfnh8m6cxaysa9bafmp2z-redis-config.json.drv'...
/nix/store/6v88ick1cxnn5g91m8qrrqww0lrlr27x-bash-4.4-p23/bin/bash: /nix/store/6v88ick1cxnn5g91m8qrrqww0lrlr27x-bash-4.4-p23/bin/bash: cannot execute binary file
builder for '/nix/store/jsydsrzs7h9pfnh8m6cxaysa9bafmp2z-redis-config.json.drv' failed with exit code 126
cannot build derivation '/nix/store/pyx4q2wln2shlnjdp5ng43aqd6iba80d-docker-image-redis.tar.gz.drv': 1 dependencies couldn't be built
error: build of '/nix/store/pyx4q2wln2shlnjdp5ng43aqd6iba80d-docker-image-redis.tar.gz.drv' failed
这里的关键是/nix/store/6v88ick1cxnn5g91m8qrrqww0lrlr27x-bash-4.4-p23/bin/bash: cannot execute binary file
.用file
它来检查,它确实是一个 Linux ELF 二进制文件。
顺便说一句,同样的事情也发生在下面的一句话中,取自 StackOverflow 问题的答案如何使用 Nix 构建 Docker 容器?,同样使用 dockerTools:
$ nix-build -j 1 --system x86_64-linux -E 'with import <nixpkgs> {}; pkgs.dockerTools.buildImage { name = "nix-htop"; contents = pkgs.htop; config = { Cmd = [ "/bin/htop" ]; }; }'
...同样失败:
building path(s) ‘/nix/store/gz4lrsjcmxbcmdfpmazwz0wqnb5pbw8k-nix-htop-config.json’
/nix/store/nkq0n2m4shlbdvdq0qijib5zyzgmn0vq-bash-4.4-p12/bin/bash: /nix/store/nkq0n2m4shlbdvdq0qijib5zyzgmn0vq-bash-4.4-p12/bin/bash: cannot execute binary file
builder for ‘/nix/store/487mmw8kql56q7h6iq4c7hfzh4k0gv50-nix-htop-config.json.drv’ failed with exit code 126
dockerTools
共同点在这里吗?
答案1
这个答案为我工作。--system x86_64-linux
您可以使用--argstr system x86_64-linux
像这样的 nix 表达式,而不是使用
{ system ? "x86_64-linux", pkgs ? import <nixpkgs> { inherit system; } }:
...
例如
nix-build -j 1 --argstr system x86_64-linux -E '{ system ? "x86_64-linux", pkgs ? import <nixpkgs> { inherit system; } }: pkgs.dockerTools.buildImage { name = "nix-htop"; contents = pkgs.htop; config = { Cmd = [ "/bin/htop" ]; }; }'