node.js - 如何在 Nix Docker Tools 映像中包含我的源代码?
问题描述
我正在使用 NodeJS 构建 Web 服务器,并且正在使用 Nix 提供的Docker 工具为我的服务器构建图像。
我有以下要转换为.nix
文件的 Dockerfile
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 语言基础架构(如yarn2nix
)node2nix
或其他语言的各种工具来构建软件。通过这样做,您的构建变得可重现,它往往更具增量性,您不必担心源文件或中间文件最终会出现在您的容器映像中。
我还建议将contents
参数限制为 apkgs.buildEnv
或pkgs.symlinkJoin
调用,因为内容被复制到容器的根目录,同时也保留在其存储中。
*:足够简单不包括获取单个资源之外的任何内容,因为这往往太脆弱了。如果出于任何原因,固定输出派生构建器产生了不同的结果,并且修复它的唯一方法是更改输出哈希,那么您的整个构建基本上是不可重现的。
推荐阅读
- bash - curl命令中的bash脚本变量替换
- python - 为什么sklearn MinMaxScaler归一化稀疏矩阵只会输出-1和1值
- td-engine - tdengine 数据库中的多级存储
- python - 如何在 twint 中使用 since 和 until 参数?
- python - 如何使用 django 将来自 chromedriver 的文件正确保存在 docker 容器中?
- django - 为什么 Django 开发服务器没有重新加载?
- reactjs - 动态填充菜单组件 - React Material UI
- wordpress - 更改 Wordpress 网站的域名
- python - 直接运行 rasa 服务器,而不是从源环境?
- kubernetes - 在 1.20.8-gke.900 集群中找不到 GKE MultidimPodAutoscaler