微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Nix Docker 工具映像中包含我的源代码?

如何解决如何在 Nix Docker 工具映像中包含我的源代码?

我正在使用 NodeJS 构建网络服务器,我正在使用 Nix 提供的 Docker Tools 为我的服务器构建图像。

我有以下 Dockerfile,我想将其转换为 .nix 文件

FROM node:12.20.0-alpine3.11 as build-deps
workdir /hedwig-app
copY ["package.json","package-lock.json*","./"]
RUN npm install
copY . .
RUN npm run build
EXPOSE 8080
CMD [ "node","build/index.js" ]

但是,我不知道如何将我的源代码复制到要构建的Docker镜像中。这是我目前所拥有的

{ pkgs ? import <nixpkgs> {} }:

let
    baseImage = pkgs.dockerTools.pullImage {
        imageName = "alpine";
        imageDigest = "sha256:3c7497bf0c7af93428242d6176e8f7905f2201d8fc5861f45be7a346b5f23436";
        sha256 = "119pbb2nrhs6nvbhhpcd52fqy431ag46azgxvgdmyxrwii97f4ah";
        finalImageName = "alpine";
        finalImageTag = "3.12";
    };
    sourceFiles = builtins.toString ./.;
    gitignoreSrc = pkgs.fetchFromGitHub { 
        owner = "hercules-ci";
        repo = "gitignore";
        # put the latest commit sha of gitignore Nix library here:
        rev = "c4662e662462e7bf3c2a968483478a665d00e717";
        # use what nix suggests in the mismatch message here:
        sha256 = "sha256:1npnx0h6bd0d7ql93ka7azhj40zgjp815fw2r6smg8ch9p7mzdlx";
    };
    inherit (import gitignoreSrc { inherit (pkgs) lib; }) gitignoreSource;
    src = gitignoreSource ./.;
in
    pkgs.dockerTools.buildImage {
        name = "hedwig-api";
        tag = "latest";

        fromImage = baseImage;
        contents = [ pkgs.nodejs ];
        runAsRoot = ''
        mkdir /hedwig-app
        cp -r ${src} /hedwig-app
        npm install
        npm run build
        '';

        config = {
            ExposedPorts = {
                "8080/tcp" = {};
            };
            WorkingDir = "/hedwig-app";
            Cmd = ["node" "build/index.js"];
        };
    }

如何在运行 npm run build 之前将我的源代码复制到图像中?

解决方法

在 Nix 中,您无法运行 npm install。每个步骤只能做两件事之一:

  • 在没有网络访问的情况下计算新的商店路径:常规推导
  • 或者使用可以访问网络的足够简单的*过程生成满足硬编码散列的输出:固定输出推导

这些约束确保构建极有可能重现。

npm install 需要访问网络以获取其依赖项,这将其置于固定输出派生类别中。但是,dockerTools.buildImage 会在常规派生中执行它,因此将无法联系 npmjs 存储库。

因此,我们通常无法将 Dockerfile 直接映射到一系列 buildImage 调用。相反,我们可以使用 Nix 语言基础架构(如 yarn2nixnode2nix 或其他语言的各种工具)构建软件。 通过这样做,您的构建变得可重现,它往往会更加增量,您不必担心源文件或中间文件最终会出现在您的容器映像中。

我还建议将 contents 参数限制为 pkgs.buildEnvpkgs.symlinkJoin 调用,因为内容被复制到容器的根目录同时还留在其商店中。


*:足够简单排除了除了获取单个资源之外的任何东西,因为这往往太脆弱了。如果出于任何原因,固定输出派生构建器产生了不同的结果,而修复它的唯一方法是更改​​输出哈希,那么您的整个构建基本上是不可重现的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。