使用建構快取

說明

請參考您為 入門 應用程式建立的 Dockerfile。

FROM node:20-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "./src/index.js"]

當您執行 docker build 命令來建立新的映像檔時,Docker 會執行 Dockerfile 中的每個指令,並按照指定的順序為每個命令建立一個層。對於每個指令,Docker 會檢查是否可以重複使用先前建構中的指令。如果發現您之前已經執行過類似的指令,Docker 就不需要重新執行。相反地,它會使用快取的結果。如此一來,您的建構過程會變得更快、更有效率,節省您寶貴的時間和資源。

有效地使用建構快取,可以讓您透過重複使用先前建構的結果並跳過不必要的工作,來加快建構速度。為了最大限度地利用快取並避免資源密集且耗時的重建,了解快取失效的運作方式非常重要。以下是一些可能導致快取失效的情況範例

  • RUN 指令命令的任何變更都會使該層失效。如果 Dockerfile 中的 RUN 命令有任何修改,Docker 會偵測到變更並使建構快取失效。

  • 使用 COPYADD 指令複製到映像檔中的檔案的任何變更。Docker 會密切注意專案目錄中檔案的任何變更。無論是內容變更還是權限等屬性變更,Docker 都將這些修改視為使快取失效的觸發因素。

  • 一旦某個層失效,所有後續的層也會失效。如果任何先前的層(包括基礎映像檔或中間層)由於變更而失效,Docker 會確保依賴它的後續層也失效。這可以保持建構過程同步,並防止出現不一致的情況。

撰寫或編輯 Dockerfile 時,請注意不必要的快取遺漏,以確保建構過程盡可能快速有效地執行。

試用看看

在本實作指南中,您將學習如何有效地將 Docker 建構快取用於 Node.js 應用程式。

建構應用程式

  1. 下載並安裝複製此範例應用程式

  • 瀏覽至 todo-list-app 目錄

    在此目錄中,您會找到一個名為 Dockerfile 的檔案,其中包含以下內容

  • 執行以下命令來建構 Docker 映像檔

    以下是建構過程的結果

    第一行表示整個建構過程花費了 *20.0 秒*。第一次建構可能需要一些時間,因為它會安裝相依性。

  • 在不做任何變更的情況下重建。

    現在,重新執行 docker build 命令,而不對原始程式碼或 Dockerfile 進行任何變更,如下所示

    由於快取機制,只要命令和上下文保持不變,初始建構之後的後續建構就會更快。Docker 會快取建構過程中產生的中間層。當您在不對 Dockerfile 或原始程式碼進行任何變更的情況下重建映像檔時,Docker 可以重複使用快取的層,從而顯著加快建構過程。

    後續建構透過利用快取層,僅在 1.0 秒內完成。無需重複耗時的步驟,例如安裝相依性。

    步驟說明花費時間(第一次執行)花費時間(第二次執行)
    1從 Dockerfile 載入建構定義0.0 秒0.0 秒
    2載入 docker.io/library/node:20-alpine 的中繼資料2.7 秒0.9 秒
    3載入 .dockerignore0.0 秒0.0 秒
    4載入建構上下文

    (上下文大小:4.60MB)

    0.1 秒0.0 秒
    5設定工作目錄 (WORKDIR)0.1 秒0.0 秒
    6將本機程式碼複製到容器中0.0 秒0.0 秒
    7執行 yarn install --production10.0 秒0.0 秒
    8匯出層2.2 秒0.0 秒
    9匯出最終映像檔3.0 秒0.0 秒

    回到 docker image history 輸出,您會看到 Dockerfile 中的每個命令都會成為映像檔中的一個新層。您可能記得,當您對映像檔進行變更時,必須重新安裝 yarn 相依性。有沒有辦法解決這個問題?每次建構都重新安裝相同的相依性沒有什麼意義,對吧?

    要解決此問題,請重新建構 Dockerfile,以便相依性快取保持有效,除非真的需要使其失效。對於基於 Node 的應用程式,相依性定義在 package.json 檔案中。如果該檔案發生變更,您需要重新安裝相依性,但如果檔案未變更,則使用快取的相依性。因此,首先只複製該檔案,然後安裝相依性,最後複製其他所有內容。然後,只有在 package.json 檔案發生變更時,才需要重新建立 yarn 相依性。

  • 更新 Dockerfile 以先複製 package.json 檔案,安裝相依性,然後再複製其他所有內容。

  • 在與 Dockerfile 相同的資料夾中建立一個名為 .dockerignore 的檔案,其中包含以下內容。

  • 建構新的映像檔

    然後您將看到類似以下的輸出

    您將看到所有層都已重建。由於您對 Dockerfile 進行了相當大的變更,因此完全沒有問題。

  • 現在,對 src/static/index.html 檔案進行變更(例如將標題更改為「超棒的待辦事項應用程式」)。

  • 建構 Docker 映像檔。這次,您的輸出應該看起來有些不同。

    然後您將看到類似以下的輸出

    首先,您應該會注意到建置速度變得更快了。您會看到幾個步驟正在使用先前快取的層。這是個好消息;您正在使用建置快取。推送和提取此映像及其更新也會快得多。

  • 透過遵循這些最佳化技巧,您可以使 Docker 建置速度更快、效率更高,從而加快迭代週期並提高開發效率。

    其他資源

    後續步驟

    現在您已了解如何有效地使用 Docker 建置快取,接下來可以學習多階段建置。