Docker 的快取機制是提升映象建置效率的關鍵。Docker 映象採分層結構,每一步操作都會生成一個新的層。當 Dockerfile 沒有變更時,Docker 會直接使用快取的層,避免重複建置,進而縮短建置時間。這對於頻繁修改程式碼並重新建置映象的開發流程來說至關重要,尤其在 CI/CD 流程中,能有效減少每次建置所需的時間。瞭解 Docker 的快取機制,可以幫助開發者編寫更有效率的 Dockerfile,並最佳化容器化應用程式的佈署流程。

Docker 檔案製作與快取機制詳解

在容器化的開發流程中,Dockerfile 是定義容器環境的核心檔案。本章節將探討 Dockerfile 的製作過程,以及 Docker 的快取機制。

Docker 快取機制原理

Docker 映象的結構是由多個層(layer)堆積疊而成,每一層代表著對映象的無狀態變更。當重建映象時,Docker 會從上到下檢查每一層是否有變更。如果只有最上層的程式碼發生變化,那麼只有這一層需要被重建。

快取機制運作範例

首先,我們來檢視 Docker 快取的工作方式。假設我們有一個名為 joshuacook/gsl 的映象,其 Dockerfile 內容如下:

FROM gcc
LABEL maintainer=@joshuacook
RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl

現在,我們在 Dockerfile 中新增一個安裝 gdb 的層:

RUN apt-get update && \
    apt-get install -y gdb

內容解密:

  1. FROM gcc:使用官方的 GCC 映象作為基礎映象。
  2. LABEL maintainer=@joshuacook:為映象新增維護者標籤。
  3. RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl:安裝 GSL 相關套件。
  4. RUN apt-get install -y gdb:新增一個層來安裝 gdb 除錯工具。

執行建置指令:

$ docker build -t joshuacook/gsl gsl

輸出結果顯示,步驟 1-3 因為沒有變化而使用了快取,只有步驟 4 被執行。

Step 1/4 : FROM gcc
---
> 408d218617ca
Step 2/4 : LABEL maintainer @joshuacook
---
> Using cache
---
> ba0d6482c28a
Step 3/4 : RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl
---
> Using cache
---
> 8706282586fc
Step 4/4 : RUN apt-get install -y gdb
---
> Running in c491003e5a95
...
---
> 53111721b96a
Removing intermediate container c491003e5a95
Successfully built 53111721b96a

再次執行相同的建置指令,會發現所有步驟都使用了快取:

$ docker build -t joshuacook/gsl gsl
Step 1/4 : FROM gcc
---
> 408d218617ca
Step 2/4 : LABEL maintainer @joshuacook
---
> Using cache
---
> ba0d6482c28a
Step 3/4 : RUN apt-get update && apt-get install -y gsl-bin libgsl0-dbg libgsl0-dev libgsl0ldbl
---
> Using cache
---
> 8706282586fc
Step 4/4 : RUN apt-get install -y gdb
---
> Using cache
---
> 53111721b96a
Successfully built 53111721b96a

快取機制優點

  1. 提升建置效率:未變更的層可以直接使用快取,避免重複建置。
  2. 冪等性:多次執行相同的建置指令不會產生額外效果。

建立 Miniconda3 映象

Miniconda 是 Anaconda 的精簡版本,用於管理 Python 和 R 語言環境。我們將建立一個自定義的 Miniconda3 映象。

建立 Miniconda3 映象步驟

  1. 建立專案目錄
$ mkdir miniconda3
$ touch miniconda3/Dockerfile
  1. 定義 Dockerfile
FROM debian
LABEL maintainer=@joshuacook
ARG DEBIAN_FRONTEND=noninteractive

內容解密:

  1. FROM debian:使用 Debian 作為基礎映象。

  2. LABEL maintainer=@joshuacook:新增維護者資訊。

  3. ARG DEBIAN_FRONTEND=noninteractive:定義環境變數,避免互動式提示。

  4. 建置 Miniconda3 映象

$ docker build -t miniconda3 miniconda3
  1. 檢視建置結果
$ docker images

輸出結果顯示,新建的 miniconda3 映象與 debian 映象共用相同的 IMAGE ID,因為它們實際上是相同的映象。

重複建置測試

再次執行建置指令,可以觀察到快取的使用情況:

$ docker build -t miniconda3 miniconda3
Step 1/3 : FROM debian
---
> a2ff708b7413
Step 2/3 : LABEL maintainer @joshuacook
---
> Using cache
---
> c140313c988e
Step 3/3 : ARG DEBIAN_FRONTEND=noninteractive
---
> Running in b927c25267f0
---
> da987fd59d24
Removing intermediate container b927c25267f0
Successfully built da987fd59d24

重點整理

  1. Docker 快取機制可以顯著提升映象建置效率。
  2. 適當使用 ARG 和 ENV 指令可以靈活組態容器環境。
  3. 建立自定義 Miniconda3 映象可以用於科學計算和資料分析環境。

透過本章節的學習,我們深入瞭解了 Dockerfile 的製作流程和 Docker 的快取機制,這些知識對於高效使用 Docker 技術至關重要。

第5章:Dockerfile 詳解

在前面的章節中,我們已經成功建立了一個基本的 Docker 映像檔。本章將探討 Dockerfile 的編寫,以建立一個完整的 Miniconda3 環境。

Dockerfile 的基本結構

Dockerfile 是一種特殊的檔案,用於定義 Docker 映像檔的構建過程。它包含了一系列的指令,用於指定基礎映像檔、安裝軟體、設定環境變數等。

編寫 Dockerfile

首先,我們需要建立一個名為 miniconda3 的目錄,並在其中建立一個名為 Dockerfile 的檔案。

步驟1:指定基礎映像檔

我們的第一步是指定基礎映像檔。在這個例子中,我們使用 Debian 作為基礎映像檔。

FROM debian

步驟2:新增 LABEL 和 ARG 指令

接下來,我們新增一個 LABEL 指令來指定維護者的資訊,並使用 ARG 指令來設定環境變數。

LABEL maintainer="@joshuacook"
ARG DEBIAN_FRONTEND=noninteractive

步驟3:佈建作業系統

為了讓我們的 Miniconda3 環境能夠正常運作,我們需要安裝一些必要的軟體套件。

RUN apt-get update --fix-missing && \
    apt-get install -y \
    wget bzip2 ca-certificates \
    libglib2.0-0 libxext6 libsm6 libxrender1

#### 內容解密:

這段程式碼的作用是更新 Debian 的套件清單,並安裝必要的軟體套件。其中,apt-get update 用於更新套件清單,apt-get install 用於安裝指定的軟體套件。我們使用 -y 引數來自動確認安裝,並使用 \ 來將指令分成多行,以提高可讀性。

步驟4:安裝 Miniconda3

接下來,我們需要安裝 Miniconda3。

RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
    wget --quiet https://repo.continuum.io/miniconda/Miniconda3-4.3.11-Linux-x86_64.sh -O ~/miniconda.sh && \
    /bin/bash ~/miniconda.sh -b -p /opt/conda && \
    rm ~/miniconda.sh

#### 內容解密:

這段程式碼的作用是安裝 Miniconda3。首先,我們建立一個名為 conda.sh 的檔案,用於設定環境變數。然後,我們下載 Miniconda3 的安裝指令碼,並執行它。最後,我們刪除安裝指令碼,以節省空間。

步驟5:安裝 tini

為了避免容器中的 Zombie 程式,我們需要安裝 tini。

RUN apt-get install -y curl grep sed dpkg && \
    TINI_VERSION=`curl https://github.com/krallin/tini/releases/latest | grep -o "/v.*\"" | sed 's:^..\(.*\).$:\1:'` && \
    curl -L "https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini_${TINI_VERSION}.deb" > tini.deb && \
    dpkg -i tini.deb && \
    rm tini.deb && \
    apt-get clean

#### 內容解密:

這段程式碼的作用是安裝 tini。首先,我們安裝必要的軟體套件,如 curlgrepsed。然後,我們取得 tini 的最新版本,並下載對應的 deb 檔案。接著,我們安裝 tini,並刪除 deb 檔案。最後,我們清理套件快取,以節省空間。

建構 Docker 映像檔

完成 Dockerfile 的編寫後,我們可以使用 docker build 指令來建構 Docker 映像檔。

$ docker build -t miniconda3 miniconda3

這個指令會根據 Dockerfile 中的指令,逐步建構 Docker 映像檔。建構完成後,我們可以使用 docker images 指令來檢視映像檔的資訊。

提交變更

在每次修改 Dockerfile 後,我們都需要提交變更到本地儲存函式庫。

$ git add Dockerfile
$ git commit -m 'MINICONDA3 IMAGE. 新增 LABEL 和 ARG 指令.'

這樣,我們就可以追蹤每次變更的內容,並方便地回溯到之前的版本。

第 5 章:Dockerfile 詳解

本章主要介紹 Dockerfile 的基本概念及其在 Docker 環境中的重要性。Dockerfile 是一種文字檔案,用於定義 Docker 映像的構建過程。透過 Dockerfile,可以自動化地構建和佈署 Docker 映像。

組態環境變數

為了確保容器能夠正常執行,需要組態一些環境變數。在 Dockerfile 中,可以使用 ENV 指令來設定環境變數。

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
ENV PATH /opt/conda/bin:$PATH

內容解密:

  1. ENV LANG=C.UTF-8 LC_ALL=C.UTF-8:設定語言環境變數為 C.UTF-8,確保容器內的語言設定正確。
  2. ENV PATH /opt/conda/bin:$PATH:將 /opt/conda/bin 新增到系統的 PATH 環境變數中,確保 conda 相關的命令可以被正確執行。

設定 ENTRYPOINT

ENTRYPOINT 指令用於指定容器啟動時要執行的程式。在本例中,使用 tini 作為容器內的初始化程式。

ENTRYPOINT [ "/usr/bin/tini", "--" ]

內容解密:

  1. ENTRYPOINT [ "/usr/bin/tini", "--" ]:指定 /usr/bin/tini 為容器的入口點,並傳遞 -- 引數。tini 是一個輕量級的初始化系統,用於處理訊號和子程式。

建構 miniconda3 映像

使用 docker build 命令來建構 miniconda3 映像。

$ docker build -t miniconda3 miniconda3

內容解密:

  1. $ docker build -t miniconda3 miniconda3:使用當前目錄下的 Dockerfile 建構一個名為 miniconda3 的映像。

建構 ipython 映像

miniconda3 映像的基礎上,建構 ipython 映像。首先建立一個新的目錄,並在其中建立 Dockerfile。

$ mkdir ipython
$ touch ipython/Dockerfile

內容解密:

  1. $ mkdir ipython:建立一個名為 ipython 的目錄。
  2. $ touch ipython/Dockerfile:在 ipython 目錄下建立一個空的 Dockerfile。

定義 ipython 映像

在 Dockerfile 中,使用 FROM 指令指定基礎映像,並安裝 ipython

FROM miniconda3
LABEL maintainer=@joshuacook
RUN conda update conda && \
    conda install --quiet --yes ipython && \
    conda clean -tipsy
CMD ["ipython"]

內容解密:

  1. FROM miniconda3:指定 miniconda3 為基礎映像。
  2. LABEL maintainer=@joshuacook:新增維護者資訊。
  3. RUN conda update conda && conda install --quiet --yes ipython && conda clean -tipsy:更新 conda,安裝 ipython,並清理無用的檔案。
  4. CMD ["ipython"]:指定容器啟動時預設執行的命令為 ipython

建構和執行 ipython 映像

使用 docker build 命令建構 ipython 映像,並使用 docker run 命令執行該映像。

$ docker build -t ipython ipython
$ docker run -it ipython

內容解密:

  1. $ docker build -t ipython ipython:建構 ipython 映像。
  2. $ docker run -it ipython:以互動模式執行 ipython 容器。

提交變更到 GitHub

將變更提交到本地倉函式庫,並推播到 GitHub。

$ git add ipython/Dockerfile
$ git commit -m 'IPYTHON. Initial build'
$ git push

內容解密:

  1. $ git add ipython/Dockerfile:將 ipython/Dockerfile 新增到暫存區。
  2. $ git commit -m 'IPYTHON. Initial build':提交變更,並新增提交訊息。
  3. $ git push:將變更推播到 GitHub。

第 6 章:Docker Hub 詳解

Docker Hub 是 Docker 的官方倉函式庫,用於儲存和分發 Docker 映像。本章將介紹 Docker Hub 的基本概念和使用方法。

Docker Hub 簡介

Docker Hub 是 Docker 的官方倉函式庫,提供了豐富的 Docker 映像資源。使用者可以在 Docker Hub 上搜尋、下載和使用各種 Docker 映像。

使用 Docker Hub

使用者可以在 Docker Hub 上建立自己的倉函式庫,並上傳自己的 Docker 映像。同時,也可以瀏覽和下載其他使用者分享的 Docker 映像。

Docker Hub 的替代方案

除了 Docker Hub 之外,還有其他一些 Docker 倉函式庫可供選擇,例如 Quay.io 和 Google Container Registry。這些倉函式庫提供了不同的功能和特性,可以根據實際需求進行選擇。