将 node_modules 复制到 dockerfile 与安装它们

J. *_*son 7 dependencies node.js node-modules docker dockerfile

我\xe2\x80\x99 的任务是在工作中对我们的 Node 应用程序进行 docker 化。当谈到node_modules时,我与我们的首席开发人员有点分歧。

\n

他在 dockerfile 中提倡类似的东西。他的理由是 docker 镜像将更具确定性,在这一点上我不\xe2\x80\x99t 完全不同意他的观点。

\n
COPY node_modules ./\n
Run Code Online (Sandbox Code Playgroud)\n

我提倡这样的事情。我的推理.. \xe2\x80\x99 本质上是互联网上每个人都说的做法,包括Node 文档Docker 文档。我希望我是从技术角度争论的,但我似乎只能\xe2\x80\x99t 找到任何专门解决这个问题的东西。

\n
COPY package*.json ./\nRUN npm install\n
Run Code Online (Sandbox Code Playgroud)\n

那么谁是对的呢?第一种选择有哪些缺点?

\n

Dav*_*aze 11

我几乎总是从容器内部安装 Node 包,而不是COPY从主机安装它们(RUN npm ci如果我使用 npm,可能是通过)。

如果主机环境与容器环境不完全匹配,COPY则主机node_modules目录可能无法正常工作(或根本无法工作)。最明显的例子是使用带有 Linux 容器的 MacOS 或 Windows 主机,如果存在任何 C 扩展或其他二进制文件,它们将无法工作。如果 Node 版本不完全匹配,也可能会出现这种情况。最后,个别开发人员可能已经npm install编写了额外的包或不同的版本,并且映像会根据构建者的不同而有所不同。

还可以考虑使用多阶段构建来同时拥有开发版本和生产版本的方法node_modules;这样,您就不会tsc在最终映像中包含仅构建的工具,例如 Typescript 编译器。如果您有两个不同版本,node_modules则无法COPY从主机获取单个树,则必须将其安装在 Dockerfile 中。

FROM node AS build
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
RUN npm install

FROM node
WORKDIR /app
COPY package*.json .
ENV NODE_ENV=production
RUN npm ci
COPY --from=build /app/build /app/build
CMD ["node", "/app/build/index.js"]
Run Code Online (Sandbox Code Playgroud)