Nix
在 MacOS 主機的 nix dockerTools 交叉建構期間“bash:無法執行二進製文件”
一篇很棒的 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" = {}; }; }; }
使用有一個 x86_64-linux 建構器,這將失敗,並出現有關無法執行
nix-linuxkit
的執行檔的錯誤:bash
$ 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 問題How to build a Docker container with Nix?的回答。,也使用 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
共同點在這裡嗎?
這個答案對我有用。而不是 using
--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" ]; }; }'