node.js - nodejs - dockerfile教學




在Docker構建Dockerfile時如何緩存RUN npm安裝指令 (4)

奇怪的! 沒有人提到 多階段構建

# ---- 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

很棒的tuto在這裡: https://codefresh.io/docker-tutorial/node_docker_multistage/ ://codefresh.io/docker-tutorial/node_docker_multistage/

我目前正在為我的應用程序開發Node後端。 在對它進行docker化(docker build。)時,最長的階段是 RUN npm installRUN npm install 指令在每個小的服務器代碼更改上運行,通過使開發人員每次都等待構建完成來影響生產率。

我發現在應用程序代碼所在的位置運行npm install並使用ADD指令將node_modules添加到容器中可以解決此問題,但這遠非最佳實踐。 這有點破壞了將其Docker化的整個想法,並且使容器的重量增加了很多。

還有其他解決方案嗎?


好的,所以我發現 了這篇 有關寫docker文件時效率的 精彩文章

這是一個錯誤的docker文件在運行 RUN npm install 指令之前添加應用程序代碼的示例:

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安裝指令,只有package.json的更改才會觸發它。 更好地實踐docker文件:

FROM ubuntu
MAINTAINER David Weinstein <[email protected].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構建上的npm安裝階段,只需複制這些行並將^ / opt / app ^更改為您的應用在容器中的位置。


我想您可能已經知道,但是您可以在包含以下內容的同一文件夾中包含一個.dockerignore文件

node_modules
npm-debug.log

避免在推送到Docker Hub時使圖像image腫


我發現最簡單的方法是利用Docker的複制語義:

COPY指令從中復制新文件或目錄,並將它們添加到路徑中容器的文件系統中。

這意味著,如果您首先顯式複制 package.json 文件,然後運行 npm install 步驟,則可以對其進行緩存,然後可以復制源目錄的其餘部分。 如果 package.json 文件已更改,則它將是新的,它將重新運行npm install緩存,以供將來構建。

Dockerfile末尾的代碼段如下所示:

# install node modules
WORKDIR  /usr/app
COPY     package.json /usr/app/package.json
RUN      npm install

# install application
COPY     . /usr/app






dockerfile