docker image 縮小約一半
的空間,
過去對於 docker file 並沒有花太多時間深入了解,而且產生的 output 也沒發現太多問題,因此也錯過了學習的機會。直到有一天,在捷運的路上,看到一篇 twitter 在介紹 node.js docker file best practices,於是開始認真檢視先前在專案中的 docker file 的內容。
這一篇主要是將重點以條列方式凸顯,內容包含了一個簡單的例子。同時在文章結尾處附上一些不錯的文章提供大家參考,有興趣的人可以動手做一遍,即可產生一份有品質的 docker file。
FROM node:14.17.0-alpine
RUN apk --update --no-cache add python build-base
WORKDIR /usr/src/app
COPY .npmrc package*.json ./
RUN npm install --only=production
COPY . .
EXPOSE 4001
CMD ["npm", "start"]
這一份簡單的 docker file 暴露了幾個問題:
它沒有採用 multi-stage builds,因此在 node build 的過程中產生了很多不必要的檔案
,既浪費了空間
,影響到執行 container 的速度
,額外不必要的程式存在 image 中,更是增加了暴露安全性漏洞
的機會。
安全性方面,在執行此程式時,採用 root
的最大權限更是致命傷。比較理想的方式是限制檔案與授予足夠執行程式的權限
即可。
最後,關於 node 有許多小細節也沒有注意到。關於這些細節,在官方的 best practices 都有提及,有興趣的人可以花時間了解。
透過以下的方式不僅讓 docker image 縮小約一半的空間,同時也提升了安全性,避免賦予 root 的權限,同時在選擇 base image 時,可以了解其 vulnerability。
先執行 run (package installation) 在執行 copy 可減少因為 source code 的修改而造成 layer 無法重複利用
RUN --mount=type=cache,target=/usr/src/app/.npm \\
npm set cache /usr/src/app/.npm && \\
# "--omit=dev" not necessary since ENV NODE_ENV production is set
# We make it obvious here
npm ci --omit=dev
COPY . .