docker构建Dockerfile时如何缓存RUN npm install指令

新手上路,请多包涵

我目前正在为我的应用程序开发 Node 后端。当对它进行 dockerizing ( docker build . ) 时,最长的阶段是 RUN npm installRUN npm install 指令在每个小的服务器代码更改上运行,这会通过增加构建时间来阻碍生产力。

我发现在应用程序代码所在的位置运行 npm install 并使用 ADD 指令将 node_modules 添加到容器中可以解决此问题,但这远非最佳实践。它有点打破了将它码头化的整个想法,并导致容器更重。

还有其他解决方案吗?

原文由 ohadgk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

好的,所以我在编写 docker 文件时发现 了这篇关于效率的好文章

这是在运行 RUN npm install 指令之前添加应用程序代码的错误 docker 文件的示例:

 FROM ubuntu

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs

WORKDIR /opt/app

COPY . /opt/app
RUN npm install
EXPOSE 3001

CMD ["node", "server.js"]

通过将应用程序的副本分成 2 个 COPY 指令(一个用于 package.json 文件,另一个用于其余文件)并在添加实际代码之前运行 npm install 指令,任何代码更改都不会触发 RUN npm install指令,只有 package.json 的变化才会触发它。更好的实践 docker 文件:

 FROM ubuntu
MAINTAINER David Weinstein <david@bitjudo.com>

# install our dependencies and nodejs
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get -y install python-software-properties git build-essential
RUN add-apt-repository -y ppa:chris-lea/node.js
RUN apt-get update
RUN apt-get -y install nodejs

# use changes to package.json to force Docker not to use the cache
# when we change our application's nodejs dependencies:
COPY package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/

# From here we load our application's code in, therefore the previous docker
# "layer" thats been cached will be used if possible
WORKDIR /opt/app
COPY . /opt/app

EXPOSE 3000

CMD ["node", "server.js"]

这是添加 package.json 文件的地方,安装它的依赖项并将它们复制到应用程序所在的容器 WORKDIR 中:

 ADD package.json /tmp/package.json
RUN cd /tmp && npm install
RUN mkdir -p /opt/app && cp -a /tmp/node_modules /opt/app/

为了避免每个 docker build 上的 npm install 阶段,只需复制这些行并将 ^/opt/app^ 更改为您的应用程序在容器内的位置。

原文由 ohadgk 发布,翻译遵循 CC BY-SA 3.0 许可协议

诡异的!没有人提到 多阶段构建

 # ---- Base Node ----
FROM alpine:3.5 AS base
# install node
RUN apk add --no-cache nodejs-current tini
# set working directory
WORKDIR /root/chat
# Set tini as entrypoint
ENTRYPOINT ["/sbin/tini", "--"]
# copy project file
COPY package.json .

#
# ---- Dependencies ----
FROM base AS dependencies
# install node packages
RUN npm set progress=false && npm config set depth 0
RUN npm install --only=production
# copy production node_modules aside
RUN cp -R node_modules prod_node_modules
# install ALL node_modules, including 'devDependencies'
RUN npm install

#
# ---- Test ----
# run linters, setup and tests
FROM dependencies AS test
COPY . .
RUN  npm run lint && npm run setup && npm run test

#
# ---- Release ----
FROM base AS release
# copy production node_modules
COPY --from=dependencies /root/chat/prod_node_modules ./node_modules
# copy app sources
COPY . .
# expose port and define CMD
EXPOSE 5000
CMD npm run start

很棒的教程: https ://codefresh.io/docker-tutorial/node_docker_multistage/

原文由 Abdennour TOUMI 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题