如何挑選node docker鏡像
在使用Jenkins構建前端項目的時候遇到一點問題: node的版本問題。
由於可能編譯的項目歷史不同,所依賴的node版本也各有千秋,直接把所有項目都升級到最新的也不合理。所以必須針對不同的項目使用不同node構建環境。
想過nvm,但nvm是系統級別的環境變量切換,會導致同時運行的其他job也會使用nvm更改后的node版本。nvm只適合個人開發使用。
想過下載。最初見到公司的倉庫里會有node.gradle腳本,主要用來下載當前項目的node,然后直接用自己下載的node來構建。用起來還行,但腳本維護是一個問題,升級是一個問題,下載也是一個問題。
最終選擇用docker來構建。docker可以隨意挑選node鏡像,可以緩存。我們可以基於官方的鏡像,添加一些適合自己的依賴,比如緩存一些公共的module。
docker hub里有多個node tag,選擇哪個好呢。
google了一下,大概得出的結論是: alpine足矣。但我最終沒有選擇alpine, 后面說原因。
Node Docker tag
先來看看node官方的docker鏡像有哪些版本。
node:<version>
基於Debian,官方默認鏡像。當你不確定你需要什么的時候選擇這個就對了。這個被設計成可以丟棄的鏡像,也就是可以用作構建源碼使用。體積挺大。
node:<version>-slim
基於Debian, 刪除了很多默認公共的軟件包,只有node運行的最小環境。除非你有空間限制,否則推薦使用默認鏡像。
node:<version>-alpine
基於alpine, 比Debian小的多。如果想要最小的鏡像,可以選擇這個做為base。需要注意的是,alpine使用musl代替glibc。一些c環境的軟件可能不兼容。但大部分沒問題。
選擇
按照版本推薦。對比我們的需求,作為構建環境的化,應該選擇默認鏡像。
來對比下所謂的鏡像體積:
node 12.6.0-buster-slim e6e2b19326d7 13 hours ago 161MB
node 12.6.0-buster b6a436219112 13 hours ago 875MB
node 12.6.0-alpine a9a8b83644f7 3 weeks ago 78.8MB
在這之前先來了解下debian的發行版
Debian 10(buster) — 當前的穩定版(stable)
Debian 9(stretch) — 舊的穩定版(oldstable)
Debian 8(jessie) — 更舊的穩定版(oldoldstable)
Debian 7(wheezy) — 被淘汰的穩定版
最新的node鏡像就是基於Debian 10 buster構建的。
image的體積上, alpine幾乎比默認鏡像小10倍。即便縮減后的slim,也少一半。
再來看image體積重要不重要。大的image下載需要花時間,需要占用磁盤空間。思考一下,官方鏡像近1g,這個磁盤空間還是有的。至於下載時間,docker分層緩存機制可以使得我們只要下載一次即可。也是可以接受。
在使用鏡像的時候,docker對於共享的分層是不會復制兩份的,也就是共享一份,不會增大磁盤空間。詳細介紹見理解docker鏡像分層
關注下運行時的內存占用
sudo docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
c0affeebef3f gracious_williamson 0.00% 964KiB / 15.54GiB 0.01% 8.23kB / 0B 0B / 0B 1
c7a52376ac30 suspicious_goldstine 0.00% 2.047MiB / 15.54GiB 0.01% 9.57kB / 0B 4.13MB / 0B 1
39ae2195606d unruffled_elgamal 0.00% 1.387MiB / 15.54GiB 0.01% 12.2kB / 0B 0B / 0B 1
差別還是有的,但在可以接受的范圍內。
最重要的是,不同tag的docker鏡像運行時可以滿足需求嗎。
針對這三種鏡像,分別對vue-element-admin執行了npm install. 結果基於debian的鏡像12.6.0-buster-slim和12.6.0-buster都ok,但12.6.0-alpine 報錯了

所以呢,針對我當前作為構建環境的需求,選擇12.6.0-buster,也沒啥。
至於nodejs運行時的server,沒有實驗,感覺12.6.0-buster-slim挺好。
