Git 的 Dockerfile 策略

一、簡介

.Git 是領先的軟件開發版本控制系統。另一方面,Dockerfile 包含自動構建應用程序映像的所有命令。這兩種產品是任何尋求採用 DevOps 的人的完美組合。

在本教程中,我們將學習結合這兩種技術的一些解決方案。我們將詳細介紹每個解決方案並介紹其優缺點。

2. Git 存儲庫中的 Dockerfile

始終可以訪問 Dockerfile 中的 Git 存儲庫的最簡單解決方案是將 Dockerfile 直接保存在 Git 存儲庫中:

ProjectFolder/
 .git/
 src/
 pom.xml
 Dockerfile
 ...

上面的設置我們將允許我們訪問整個項目源目錄。 ADD命令將其包含在我們的容器中,例如:

ADD . /project/

我們當然可以限制複製到構建目錄的範圍:

ADD /build/ /project/

或者像 .jar 文件這樣的構建輸出:

ADD /output/project.jar /project/

這個解決方案的最大優點是我們可以測試任何代碼更改而無需將它們提交到存儲庫。一切都將位於同一個本地目錄中。

這裡要記住的一件事是創建一個.dockerignore file 。它類似於.gitignore文件,但在這種情況下,它從 Docker 上下文中排除了與其中的模式匹配的文件和目錄。這有助於我們避免向 Docker 構建過程發送不必要的大型或敏感文件和目錄,並可能將它們添加到圖像中。

3. 克隆 Git 存儲庫

另一個簡單的解決方案是在鏡像構建過程中獲取我們的 git 存儲庫。我們可以通過簡單地將 SSH 密鑰添加到本地存儲並調用git clone命令來實現它:

ADD ssh-private-key /root/.ssh/id_rsa
 RUN git clone [email protected]::eugenp/tutorials.git

上面的命令將獲取整個存儲庫並將其放置在我們容器./tutorials

不幸的是,這個解決方案也有一些缺點。

首先,我們將我們的私有 SSH 密鑰存儲在 Docker 鏡像中,這可能會帶來潛在的安全問題。我們可以通過使用 git 存儲庫的用戶名和密碼來應用解決方法:

ARG username=$GIT_USERNAME
ARG password=$GIT_PASSWORD
RUN git clone https://username:[email protected]::eugenp/tutorials.git

並將它們作為環境變量從我們的機器傳遞。這樣我們就可以將 git 憑據保留在我們的圖像之外。

其次,即使我們的存儲庫發生更改,此步驟也會在以後的構建中緩存。這是因為帶有a RUN命令的行不會改變,除非您在前面的步驟中破壞了緩存。雖然,我們可以通過docker build命令中–no-cache參數來解決它。

另一個小缺點是我們必須在容器中安裝 git 包。

4. 卷映射

我們可以使用的第三個解決方案是卷映射。它使我們能夠將目錄從我們的機器掛載到 Docker 容器中。它是存儲 Docker 容器使用的數據的首選機制。

我們可以通過在 Dockerfile 中添加以下行來實現:

VOLUME /build/ /project/

這將/project目錄並將其掛載到我們機器上/build

當我們的 Git 存儲庫僅用於構建過程時,卷映射將是最佳選擇。通過將存儲庫保留在容器之外,我們不會增加其大小並允許存儲庫內容超出給定容器的生命週期。

我們需要記住的一件事是卷映射為 Docker 容器提供了對掛載目錄的寫訪問權限。此功能的不當使用可能會導致 git 存儲庫目錄中發生一些不需要的更改。

5. Git 子模塊

如果我們將 Dockerfile 和源代碼保存在單獨的存儲庫中,或者我們的 Docker 構建需要多個源存儲庫,我們可能會考慮使用Git 子模塊

首先,我們必須創建一個新的 Git 存儲庫並將我們的 Dockerfile 放在那裡。接下來,我們可以通過將它們添加到 .gitmodules 文件來定義我們的子模塊:

[submodule "project"]
 path = project
 url = https://github.com/eugenp/tutorials.git
 branch = master

現在,我們可以像使用標準目錄一樣使用子模塊。例如,我們可以將其內容複製到我們的容器中:

ADD /build/ /project/

請記住,子模塊不會自動更新。我們需要運行以下 git 命令來獲取最新的更改:

git submodule update --init --recursive