如何優(yōu)化Docker鏡像的大小詳解
什么是Docker
Docker是一個(gè)開(kāi)源的虛擬化平臺(tái),可以讓開(kāi)發(fā)人員將應(yīng)用程序和依賴項(xiàng)打包在輕量級(jí)容器中,然后可以輕松地在任何環(huán)境中運(yùn)行。這樣,開(kāi)發(fā)人員可以將容器作為獨(dú)立的可移植單元在不同的環(huán)境中部署和運(yùn)行應(yīng)用程序,而不用擔(dān)心環(huán)境的差異會(huì)對(duì)應(yīng)用程序的行為產(chǎn)生影響。例如,您可以使用Docker在開(kāi)發(fā)環(huán)境中測(cè)試應(yīng)用程序,然后將容器部署到生產(chǎn)環(huán)境中運(yùn)行??傊珼ocker可以讓開(kāi)發(fā)人員更輕松地創(chuàng)建、部署和運(yùn)行應(yīng)用程序。
- 靈活性:即使是最復(fù)雜的應(yīng)用程序也可以容器化。
- 輕量化:容器共享主機(jī)內(nèi)核,使得它們遠(yuǎn)比虛擬機(jī)高效。
- 便攜性:可以做到本地編譯,到處運(yùn)行。松耦合:容器自我封裝,一個(gè)容器被替換或升級(jí)不會(huì)打斷別的容器。
- 安全性:容器對(duì)進(jìn)程進(jìn)行了嚴(yán)格的限制和隔離,而無(wú)需用戶進(jìn)行任何配置。
在這篇文章中,我將重點(diǎn)討論如何優(yōu)化 Docker 鏡像以使其輕量化。
優(yōu)化過(guò)程
讓我們從一個(gè)示例開(kāi)始,在該示例中,我們構(gòu)建了一個(gè) React 應(yīng)用程序并將其容器化。運(yùn)行 npx 命令并創(chuàng)建 Dockerfile 之后,我們得到了如圖 1 所示的文件結(jié)構(gòu)。
npx create-react-app app --template typescript
如果我們構(gòu)建一個(gè)基礎(chǔ)的 Dockerfile(如下所示),我們最終會(huì)得到一個(gè) 1.16 GB 的鏡像:
FROM node:10 WORKDIR /app COPY app /app RUN npm install -g webserver.local RUN npm install && npm run build EXPOSE 3000 CMD webserver.local -d ./build
第一步優(yōu)化:使用輕量化基礎(chǔ)鏡像
在 Docker Hub(公共 Docker 倉(cāng)庫(kù))中,有一些鏡像可供下載,每個(gè)鏡像都有不同的特征和大小。
通常,相較于基于其他 Linux 發(fā)行版(例如 Ubuntu)的鏡像,基于 Alpine 或 BusyBox 的鏡像非常小。這是因?yàn)?Alpine 鏡像和類似的其他鏡像都經(jīng)過(guò)了優(yōu)化,其中僅包含最少的必須的軟件包。
在下面的圖片中,你可以看到 Ubuntu、Alpine、Node 和基于 Alpine 的 Node 鏡像之間的大小比較。
通過(guò)修改 Dockerfile 并使用 Alpine 作為基礎(chǔ)鏡像,我們的鏡像最終大小為 330MB:
FROM node:10-alpine WORKDIR /app COPY app /app RUN npm install -g webserver.local RUN npm install && npm run build EXPOSE 3000 CMD webserver.local -d ./build
第二步優(yōu)化:多階段構(gòu)建
通過(guò)多階段構(gòu)建,我們可以在 Dockerfile 中使用多個(gè)基礎(chǔ)鏡像,并將編譯成品、配置文件等從一個(gè)階段復(fù)制到另一個(gè)階段,這樣我們就可以丟棄不需要的東西。
我們部署 React 應(yīng)用程序需要的是編譯后的代碼,我們不需要源文件,也不需要 node_modules 目錄和 package.json 文件等。
通過(guò)將 Dockerfile 修改為如下內(nèi)容,我們最終得到的鏡像大小為 91.5MB。請(qǐng)記住,來(lái)自第一階段(第 1-4 行)的鏡像不會(huì)被自動(dòng)刪除,Docker 將它保存在 cache 中,如果我們?cè)诹硪粋€(gè)構(gòu)建鏡像過(guò)程中執(zhí)行了相同的階段,就可以使鏡像構(gòu)建更快。所以你必須手動(dòng)刪除第一階段鏡像。
FROM node:10-alpine AS build WORKDIR /app COPY app /app RUN npm install && npm run build FROM node:10-alpineWORKDIR /app RUN npm install -g webserver.local COPY --from=build /app/build ./build EXPOSE 3000 CMD webserver.local -d ./build
現(xiàn)在我們有了一個(gè) Dockerfile,它有兩個(gè)階段:在第一個(gè)階段中,我們編譯項(xiàng)目,在第二個(gè)階段中,我們?cè)?web 服務(wù)器上部署應(yīng)用程序。
然而,Node 容器并不是提供網(wǎng)頁(yè)(HTML、CSS 和 JavaScript 文件、圖片等)服務(wù)的最佳選擇,最好的選擇是使用像 Nginx 或 Apache 這樣的服務(wù)。在本例中,我將使用 Nginx。
通過(guò)將 Dockerfile 修改為如下內(nèi)容,我們的鏡像最終大小是 22.4MB,如果我們運(yùn)行這個(gè)容器,我們可以看到網(wǎng)頁(yè)可以正常工作,沒(méi)有任何問(wèn)題。
FROM node:10-alpine AS build WORKDIR /app COPY app /app RUN npm install && npm run build FROM nginx:stable-alpine COPY --from=build /app/build /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
最終容器的運(yùn)行結(jié)果
總結(jié)
您可以使用多種方法來(lái)優(yōu)化Docker鏡像大小。
這里列舉幾種常用的方法:
- 使用基礎(chǔ)鏡像:選擇一個(gè)較小的基礎(chǔ)鏡像來(lái)作為您的應(yīng)用程序的鏡像。這樣,您的鏡像就不會(huì)包含多余的文件和依賴項(xiàng)。
- 使用多個(gè)鏡像:將您的應(yīng)用程序拆分成多個(gè)鏡像,每個(gè)鏡像只包含一個(gè)特定的功能。這樣,您就可以在運(yùn)行時(shí)動(dòng)態(tài)加載鏡像,而不需要在每個(gè)鏡像中都包含所有功能。
- 壓縮鏡像:使用壓縮工具對(duì)鏡像進(jìn)行壓縮,可以節(jié)省鏡像的空間。
- 清理無(wú)用文件:在構(gòu)建鏡像時(shí),確保只包含必需的文件和依賴項(xiàng)。在構(gòu)建過(guò)程中,可以使用命令來(lái)清理緩存和無(wú)用的文件。
- 使用 alpine 版本的鏡像:alpine 版本的鏡像比普通版本的鏡像要小得多,因?yàn)樗鼈冎话镜?Linux 系統(tǒng)功能。因此,您可以使用 alpine 版本的鏡像來(lái)構(gòu)建您的應(yīng)用程序。
- 刪除不必要的依賴項(xiàng):在構(gòu)建鏡像時(shí),確保只安裝必需的依賴
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一文教你如何通過(guò) Docker 快速搭建各種測(cè)試環(huán)境
這篇文章主要介紹了一文教你如何通過(guò) Docker 快速搭建各種測(cè)試環(huán)境,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07使用portainer連接遠(yuǎn)程docker的教程
Portainer是一個(gè)輕量級(jí)的docker環(huán)境管理UI,可以用來(lái)管理docker宿主機(jī)和docker swarm集群,這篇文章主要介紹了使用portainer連接遠(yuǎn)程docker的方法,需要的朋友可以參考下2020-03-03Ubuntu?環(huán)境下安裝?Docker環(huán)境詳解
這篇文章主要介紹了Ubuntu?環(huán)境下安裝?Docker環(huán)境詳解的相關(guān)資料,需要的朋友可以參考下2022-10-10修改Docker鏡像倉(cāng)庫(kù)為阿里云鏡像或163鏡像的實(shí)現(xiàn)
docker本身的倉(cāng)庫(kù)非常慢,但是國(guó)內(nèi)有阿里云的鏡像倉(cāng)庫(kù)非常快,本文主要介紹了修改Docker鏡像倉(cāng)庫(kù)為阿里云鏡像或163鏡像的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11docker 的java編譯環(huán)境構(gòu)建詳細(xì)介紹
這篇文章主要介紹了docker 的java編譯環(huán)境構(gòu)建詳細(xì)介紹的相關(guān)資料,具有一定的參考價(jià)值,需要的朋友可以參考下2016-11-11