搜尋
首頁web前端js教程聊聊如何選擇一個最好的Node.js Docker映像?

聊聊如何選擇一個最好的Node.js Docker映像?

Dec 13, 2022 pm 08:00 PM
前端node.js面試docker映像

選擇一個Node的Docker映像看起來像是一件小事,但是映像的大小和潛在漏洞可能會對你的CI/CD流程和安全造成重大的影響。那我們要如何選擇一個最好Node.js Docker映像呢?

聊聊如何選擇一個最好的Node.js Docker映像?

我們在使用FROM node:latest或只是FROM node時,很容易忽略他潛在的風險。如果你不知道整體的安全風險並且把他引入了CI/CD的流程中,那無疑是加劇了這個風險。 【相關教學推薦:nodejs影片教學程式設計教學

#下面這個範例非常典型,你可以從很多教學或部落格文章看到這個Node. js Dockerfile的配置。 但是這個Dockerfile的配置存在很大的問題,非常不推薦這樣使用:

FROM node
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm install
CMD "npm" "start"

譯者註:如果需要跳過分析直接看結論,請直接滑到文末。

一個可供選擇Node.js Docker映像

當你建立一個Node.js映像的時候,其實有很多選擇。其中就包含了Node.js核心團隊維護的官方Docker映像,以及從特定的基礎映像中選取的特殊Node.js映像版本。還可以選擇其他的,例如穀歌在distroless專案上構建的Node.js應用程序,或者是Docker官方團隊提供的一個名為scratch的鏡像。

在這些Node.js的Docker映像中,哪一個是最適合你的呢?

讓我們一個一個的去分析,了解更多他們的好處和潛在風險。

作者註:在這篇文章中,我將會比較18.2.0這個版本的Node.js鏡像,他的發佈時間是2022年6月左右。

預設的Node.js映像

我們先從維護的node映像開始。它是由進行正式地維護的,包含了一些基礎的鏡像tag。這些tag對應到不同的底層發行版(Debian、Ubuntu、Alpine)以及不同版本的Node.js運行時本身。還有針對不同CPU架構的特定版本tag,例如amd64arm64x8(新版蘋果的M1)。

Debian發行版中最常見的node鏡像,例如bullseyebuster,他們都是基於由另一個團隊維護的buildpack-deps的。
當你基於這個預設的node映像建立Node.js Docker映像時會發生什麼事?

FROM node

使用docker build --no-cache -f Dockerfile1 -t dockerfile1建構映像時,就會出現下面這些:

  • #我們沒有指定Node .js運行時版本,所以nodenode:last的一個別名,他的版本指向的是18.2.0
  • ##這個Node.js Docker映像大小是952MB
這個最新的Node.js映像的依賴和安全漏洞足跡是什麼?我們可以用

docker scan dockerfile1來運行一個Synk-powered容器,就會得到下面的結果:

    共有409個依賴項- 這些是使用作業系統套件管理員偵測到的開源程式庫,例如
  • curl/libcurl4git/git-manimagemagick/imagemagick-6-common
  • 共有289個安全問題在這些依賴中被發現,例如,
  • Buffer Overflowsuse-after-free errorsout-of-bounds write等。
  • Node.js 18.2.0運行時版本容易出現7個安全問題。例如,
  • DNS RebindingHTTP Request SmugglingConfiguration Hijacking
##譯者註:
  • Buffer Overflows - 缓冲区溢出
  • Use After Free - 一种内存破坏漏洞,通常存在于浏览器中
  • out-of-bounds write - 越界写入
  • DNS Rebinding - DNS重绑定攻击
  • HTTP Request Smugglin - HTTP请求夹带攻击技术
  • Configuration Hijacking - 配置劫持

你真的需要在Node.js镜像中给你的应用提供wgetgitcurl吗?在Node.js Docker镜像中,有成百上千个依赖和工具,而这些依赖又对应着成百上千个漏洞。Node.js运行时的特性对应着7个不同的安全漏洞,给潜在攻击留下了很大的空间。总的来说,情况并不是很乐观。

Node.js Docker Hub选项node:buster vs node:bullseye

如果你在Node.js Docker Hub仓库上浏览可用tags,你将会发现有两个Node.js镜像tags - node:busternode:bullseye

这两个Docker镜像tags都基于Debian发行版。buster镜像tag对应着Debian10,将会在2022年8月到2024年进入到他的End of Life日期,所以buster不是一个很好的选择。bullseye镜像tag对应着Debian11,被当做Debian的当前稳定版本,预计EOL日期为2026年6月。

译者注:

  • End of Life。特指产品寿命的结束,通常缩写为EOL。

因此,十分建议你将所有新的和现有的Node.js Docker镜像从node:buster迁移到node:bullseye或者其他合适的可替代版本。
我们先构建一个新的Node.js Docker镜像基于:

FROM node:bullseye复制代码

如果你构建了这个Node.js Docker镜像tag并且与之前使用node:latest的结果进行比较,将会得到完全相同的大小、依赖数量和发现的漏洞。原因是nodenode:latestnode:bullseye全部指向了同一个正在构建的Node.js镜像tag。

Node.js镜像tag瘦身

官方的Node.js团队还维护了一个显式地针对功能性Node.js环境所需工具的镜像tag并且不会存在其他的东西。

这个Node.js镜像tags是通过slim镜像tag变量来引用的,比如node:bullseye-slim,或者带有Node.js指定版本,像node:14.19.2 -slim

我们再来基于Debian的当前稳定版本的bullseye构建一个Node.jsslim镜像:

FROM node:bullseye-slim
  • 镜像的大小已经急剧下降,从接近1GB的容器镜像降到246MB的镜像大小
  • 扫描他的内容也显示了整体软件足迹的大幅下降,只有97个依赖项和56个漏洞。

就容器镜像大小和安全状况而言,node:bullseye-slim已经是一个比较好的起点了。

一个LTS的Node.js Docker镜像

到目前为止,我们的Node.js Docker镜像基于当前版本的Node.js,即Node.js18。但是根据Node.js的发布时间表,这个版本直到2022年10月才进入正式的Active LTS状态。

译者注:LTS - Long-term support,即长期支持版本。

如果我们总是依赖于我们正在构建的Node.js Docker镜像中的LTS版本的话会怎么样?我们先更新这个Docker镜像tag并构建一个新的Node.js镜像:

FROM node:lts-bullseye-slim

瘦身后的Node.js LTS版本(16.15.0)在镜像上带来了相似数量的依赖、安全漏洞和一个略小的体积(188MB)。

因此,尽管你可能需要在LTS和当前Node.js运行时版本中选择,但他们都不会对Node.js镜像的软件占用空间有大的影响。

node:alpine对于Node.js镜像来说是一个更好的选择吗?

Node.js Docker团队维护了一个node:alpine镜像tag以及他的变体,以便将Alpine Linux发行版的特定版本与Node.js运行时的特定版本进行匹配。

Alpine Linux项目经常因为其非常小的镜像体积而被引用,小体积意味着更新的软件占用空间和更少的漏洞,确实十分不错。
下面的命令会让Dockerfile去生成一个node环境,这个将会增加未压缩的镜像体积:

FROM node:alpine

这个将会产生一个178MB大小的docker镜像,和slimNode.js镜像大小差不多,但是在alpine镜像tag中,只检测到了16个系统依赖漏洞和2个安全安全漏洞。这就意味着alpine镜像tag对于小体积和漏洞数量来说是一个比较好的选择。

alpine对Node.js镜像可能提供了一个较小的镜像体积和更少的漏洞数量。但是,我们必须意识到Alpine项目使用musl作为C标准库的实现。而Debian的Node.js镜像tag依赖于glibc实现,比如bullseyeslim。这些差异可以解释性能问题、功能性的bug或者是潜在的应用程序崩溃,这些都是由于底层C库的差异造成的。

选择一个alpine的Node.js镜像tag意味着你实际上是在选择一个非官方的Node.js运行时。Node.js Docker团队并不会正式支持基于alpine的容器镜像构建。因此,他声明基于Alpine的镜像tag是实验性的,并且可能和官方的构建不一致。

如果你正在选一个一个基于Alpine的Node.js Docker镜像,需要记住一点,Docker安全工具(例如Trivy或Snyk)目前无法检测到Alpine镜像中与运行时相关的漏洞的。虽然这种情况未来可能会改变,但是目前还不能找到Node.js18.2.0alpine基础镜像tag的安全漏洞,而18.2.0运行时本身实际上是容易受到攻击的。这与安全工具本身有关,而不是与Alpine基础镜像有关,但是也应该考虑到这一点。

Node.js的distroless(无损)Docker镜像

我们的基准测试的最后一个比较项目是谷歌的Distroless容器镜像。

什么是distroless容器镜像?

这种镜像甚至比slim的Node.js镜像更加小,因为distroless镜像只针对这个应用和应用运行时的依赖性而已。因此,一个distroless的docker镜像没有容器包管理器、shell、或者其他通用工具的依赖性,这使得它们的体积更小,漏洞也更少。

幸运的是,Distroless项目为Node.js维护了一个特殊运行时的distrolessdocker镜像,通过其完整的命名空间识别为grc.io/distroless/nodejs-debian11,并且可以在谷歌的容器注册表中找到(这个是gcr.io的部分)。

因为Distroless容器镜像没有软件,我们可以使用一个docker的多阶段工作流来为我们的容器安装依赖项,并且把它们复制到Distroless镜像:

FROM node:16-bullseye-slim AS build
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm install

FROM gcr.io/distroless/nodejs:16
COPY --from=build /usr/src/app /usr/src/app
WORKDIR /usr/src/app
CMD ["server.js"]

构建这个distrolessdocker镜像将产生112MB的文件,而在slimalpine镜像tag来说,这已经减小了很多文件的体积了。
如果你正在考虑使用distrolessdocker镜像,有一些重要的事项需要注意:

  • 好的一点是,它们是基于当前稳定的Debian发行版本,这意味着它们是最新的,很久才会到EOL的日期。
  • 因为它们是基于Debian的,所以它们依赖glibc实现,并且不太可能在生产环境出现一些奇怪的问题。
  • 你很快就会发现Distroless团队没有维护细粒度的Node.js运行时版本。这意味着你需要依赖于通用的nodejs:16的标记(该标记经常更新),或者在一个特定时间点根据镜像的SHA256哈希值进行安装。

Node.js Docker镜像tags的比较

我们可以参考下面的表格来总结不同Node.js Docker镜像tags之间的比较:

##OS Critical vulnerabilitiesMedium v​​ulnerabilitiesLow vulnerabilitiesNode.js runtime vulnerabilitiesImage sizeYarn availableImage size952MB##node:bullseye 18.2.0409289#54182177952MBYesnode:bullseye-slim#18.2.0975648447#246MBYesnode:lts-bullseye-slim16.15.097554#7446188MBYesnode:alpine18.2.016220#00178MBYesgcr.io/distroless/nodejs:1616.17.09#1100110#112MBNo
Image tag Node.js runtime version OS dependencies OS security vulnerabilities #High and
node 18.2.0 #409 289 54 # 18 217 7
Yes

我們來透過之前學習到的每個不同的Node.js鏡像tags的資料和見解,然後確定哪個是最理想的。

DEVELOPMENT-PARITY(開發環境平價)

如果你選擇使用的Node.js映像tag取決於開發的一致性(這意味著你希望為開發和生產完全相同的環境進行最佳化),那麼這可能已經是一場失敗的battle了。在大多數情況下,所有3個主要作業系統都使用不同的C庫實作。 Linux依賴glibc,Alpine依賴musl,而macOS有自己的BSD libc實作。

DOCKER鏡像大小有時候,鏡像大小也很重要。更準確地說,我們的目標不是擁有最小的體積,而是擁有最小的整體軟體佔用。在這種情況下,slim鏡像tags和alpine沒有太大的區別,而且它們對於一個容器鏡像來說平均大概是200MB。當然,slim鏡像的軟體佔用相對於alpine來說還是相當高的(slim97個VS alpine16個),因此,漏洞數量對於alipne來說也更高(slime56個VS slpine

2個)。

安全漏洞

漏洞是一個重要的問題,並且一直是許多文章的中心——關於你為什麼應該減少容器鏡像的大小。 忽略nodenode:bullseye這種由於較大的軟體佔用而跟著增加安全漏洞的鏡像,我們可以更關注稍微小一點的鏡像類型。在slimalpinedistroless

之間對比,高風險和關鍵安全漏洞的絕對數量並不高,範圍在0到4之間,這是一個可控的風險,不會影響到你的應用程式。

本質內容?

最理想的Node.js Docker映像應該是基於現代Debian OS的作業系統的精簡版本,它有一個穩定且活躍的Node.js長期支援版本。 歸根究底就是選擇node:lts-bullseye-slim

Node.js鏡像tag。我贊成使用確定性圖像標記,因此我要做的細微更改是使用實際的底層版本號,而不是

lts別名。 最理想的Node.js Docker映像tag是**node:16.17.0-bullseye-slim**

如果你在一個成熟的開發團隊工作,該團隊可以支援自訂基礎鏡像,那麼我的第二個最佳建議是選擇Google的distroless

鏡像tag ,因為它保持了

glibc對官方Node.js運行時版本的兼容性。這個工作流程會需要一些維護,所以我只是建議而已。

更多node相關知識,請造訪:###nodejs 教學###! ###

以上是聊聊如何選擇一個最好的Node.js Docker映像?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具