天天看點

前端 Docker 鏡像體積優化

前端 Docker 鏡像體積優化

如果 2019 年技術圈有十大流行詞,容器化肯定占有一席之地,随着 Docker 的風靡,前端領域應用到 Docker 的場景也越來越多,本文主要來講述下開源的分布式圖資料庫 Nebula Graph 是如何将 Docker 應用到可視化界面中。

為什麼要用 Docker

對于前端日常開發而言,有時也會用到 Docker,結合到 

Nebula Graph Studio

(分布式圖資料庫 Nebula Graph 的圖形界面工具)使用 Docker 主要基于以下考慮:

  • 統一運作環境:我們的工具背後有好幾個服務組合在一起,諸如不同技術棧的現有服務,純前端的靜态資源。
  • 使用者使用成本低:目前雲服務還在開發中,想讓使用者對服務組合無感,能直接在本地一鍵啟動應用并使用。
  • 快速部署:團隊本就提供有 Nebula鏡像版本 實踐,給了我們前端一些參考和借鑒。

Docker 鏡像的建構

既然要使用 Docker 來承載我們的應用,就得将項目進行鏡像建構。與所有 build 鏡像類似,需要配置一份命名為

Dockerfile

的檔案,檔案是一些步驟的描述,簡單來說就是把項目複制到鏡像裡,并設定好啟動方式:

# 選擇基礎鏡像
FROM node:10
# 設定工作目錄
WORKDIR /nebula-web-console
# 把目前項目内容拷貝到鏡像中的 /nebula-web-console 目錄下
ADD . /nebula-web-console
# 在鏡像中下載下傳前端依賴
RUN npm install
# 執行建構
RUN npm run build
EXPOSE 7001
# 鏡像啟動時執行的部署指令
CMD ["npm", "run", "docker-start"]           

Docker 鏡像體積優化

如果按照上述的配置檔案來建構 Docker 鏡像,以我們的項目為例,将會生成一個體積約為 1.3GB 的鏡像,這個看起來有點吓人,因為即使在網速快的使用者電腦光下載下傳鏡像也需要等待不少時間,這是不能接受的。

在調研了相應的資料後,了解到可以從以下幾個方面縮小 Docker 鏡像體積進行優化:

基礎鏡像源的選擇

所謂基礎鏡像源,就是我們在進行建構步驟時,選擇的一個基礎環境(如上

node:10

 ),通過檢視

Dockerhub

上有關 Node.js 的基礎環境鏡像時,我們會發現有多個版本,雖然都是 Node.js 相關基礎鏡像,但不同版本,他們除了 Node.js 版本不同外,在内部內建的環境也不一樣,例如帶有

alpine

的版本,相當于是一個比較精巧的 Linux 系統鏡像,在此版本運作的容器中會發現不存在我們正常系統中所附帶的工具,比如 bash、curl 等,由此來縮小體積。

根據項目實際需要,當我把基礎鏡像換為

版本後,再次進行建構,此時鏡像體積已大幅度減小,從 1.3GB 直降為 500+MB,體積優化效果明顯,是以當你發現自己建構的鏡像體積過大時,可以考慮從更換基礎鏡像源的方式來着手,看看是否使用了過于臃腫的鏡像源。

Multi-stage 建構鏡像

所謂

multi-stage

即是 Docker 鏡像建構的時候采取的政策,詳細可點選連結提供的資料。

Docker 建構規則

簡言之就是利用 Docker 建構提供的規則:Dockerfile 的操作都會增加一個所謂鏡像的“層”,每一層都會增加鏡像體積,通過采用多步驟政策,每一步驟包含具有相同意義的一系列操作(例如建構,部署),步驟與步驟之間通過産物鏡像引用的方式,由此來縮減最終建構鏡像所需要的層數,具體操作比如:

# 設定第一步驟産生的鏡像,并命名為builder
FROM node:10-alpine as builder
WORKDIR /nebula-web-console
# 複制目前項目内容至鏡像中
ADD . /nebula-web-console
# 進行相應的建構
RUN npm install
RUN npm run build
....

# 進行第二步驟建構
FROM node:10-alpine
WORKDIR /nebula-web-console
# 複制第一步建構鏡像的産物内容至目前鏡像,隻用到了一層鏡像層進而節約了之前建構步驟的鏡像層數
COPY --from=builder . /nebula-web-console
CMD ["npm", "run", "docker-start"]
           

.dockerignore

類似我們熟悉的

.gitignore

 ,就是當我們在進行

COPY

ADD

檔案複制操作時,将不必要的檔案忽略掉(諸如文檔檔案、git檔案、node_modules以及一些非生成必要檔案等),進而減小鏡像體積,更詳細内容可參考文檔連接配接:

操作合并

基于上述提到在 Dockerfile 建構鏡像的過程做,每一個操作都會在前一步鏡像基礎上增加一“層”,可以利用

&

來合并多個操作,減少層數,比如:

# 以下兩個操作分别代表兩層
RUN npm install
RUN npm run build           

改為:

# 使用 & 後變了為一層
RUN npm install && npm run build           

由此我們減少了層數的增加,即減少了鏡像的體積。同時,在建構鏡像的過程中,我們也可以通過在達到相同目的的前提下,盡量減少不必要的操作來減少“層數”的添加。

前端正常性體積優化

  • 壓縮醜化代碼,移除源碼

         此操作可以放在建構步驟階段,這樣會進一步縮小鏡像的檔案體積。

  • node_modules 隻下載下傳生産環境需要的代碼

         此操作可以放在部署階段,隻下載下傳生産環境所需要的第三方依賴代碼:

    npm install --production

  • 公共資源放在CDN

         如果鏡像被期待運作在聯網環境,可以考慮将一些體積相比較大的公共檔案(圖檔、第三方庫等)放在CDN服務 器上,将部分資源剝離出去,也會進一步縮小體積。

  • ...

以上隻作為一個線索參考,更多前端正常的優化步驟,都可以遷移至鏡像中進行,畢竟和我們本地開發一樣,鏡像建構也是一個運作代碼的環境嘛。

小結

以上便是我在此次使用 Docker 鏡像來運作我們

Nebula Studio

所用到的一些優化鏡像體積的方法,希望能給需要的人一些幫助和參考,可能還有一些認識不準确的地方,歡迎指出,同樣歡迎你來試用 Nebula Graph Studio:

https://github.com/vesoft-inc/nebula-web-docker