-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Automated Build on Docker Hub with Github and Jenkins
這個實驗的目標是利用 docker hub 的 automated build 的功能,做到每次 push request 到 github 時,就能自動建立該專案的測試 image。最後希望 dockerhub build 完之後,可以通知 Jenkins,把新 build 好的 image pull 下來,啟動進行測試。
整條路徑大約是:push -> github -> dockerhub automated build -> jenkins pull images -> run containers for test -> deploy,這只是其中一種路徑,其實也可以是以 CI 為主,例如:push -> git -> Jenkins build image -> run for test -> publish this image or deploy。
關於 docker 的基礎操作,歡迎參考這份投影片:Docker Tutorial
Part I: 建立 automated build 的 Repository
- 先把 docker hub 的帳號跟 github/bitbucket 的帳號 link 起來
- 先在 Github 建好要 auto build 的專案,例如我建立了一個 https://github.com/azole/docker-auto-build-test
- 在 docker hub 按下 Add Repository,選擇 Automated Build
- 選擇 Github 或是 Bitbucket,這邊我選擇 Github
- 選擇要 build 的 Repository,我選了剛剛建立的 docker-auto-build-test
- 接下來就會出現一個設定畫面,沒有特別的 Branch 或 Tag 要選的話,用預設值就可以了。
- 按下 Create Repository,這樣就建立好了,非常地簡單。
- 這時候到 My Repositories 看看,就會看到一個 azole/docker-auto-build-test 的 repository。
- 點進去看到 repo 的細節後,點到 Build Details 這個分頁,會看到 auto-build 的結果,有 id, status 跟相關的時間註記。
- 現在會看到一個 Error 的結果,點 build Id 進去看細節,會看到 Error 的原因是 Specified Dockerfile was not found. 非常合理,因為我們沒有在這個 github 專案中放 Dockerfile。
Part II: 建立測試用的 nodejs 專案
參考 https://github.com/alsotang/node-lessons/tree/master/lesson6 的內容,建立了 nodejs 的專案,因為不是這邊的重點,就請大家自己參考該連結,或是參考 https://github.com/azole/docker-auto-build-test 裡頭的程式碼。
這個專案裡頭,我們做了一個小小的 fibonacci 的功能,並且利用 mocha 做了測試,還有一個 Makefile,也在 package.json 中寫了 npm test。
當我把測試專案做好的時候,做了一次 commit/push,回到 docker hub 上去看,會發現又多了一筆 Build Details 的記錄,這表示 Github 跟 Docker hub 真的有連動起來,不過狀態依舊是 Error,因為我們還是沒有 Dockerfile。
Part III: Dockerfile
FROM ubuntu
# install nodejs
RUN apt-get -qq update
RUN apt-get -y install nodejs
# 因為用 apt 的方式安裝的指令會是 nodejs,但個人習慣用 node,所以做個 link
RUN ln -s /usr/bin/nodejs /usr/bin/node
RUN apt-get -y install npm
# install git
RUN apt-get -y install git
# pull
RUN git clone https://github.com/azole/docker-auto-build-test.git
WORKDIR /docker-auto-build-test
RUN npm install
# run test
CMD ["npm", "test"]
這個 Dockerfile 寫好後,可以自己先 build 起來測試看看,build 後 run 起來,應該會看到測試的結果。
這時候把 Dockerfile push 上 github,這時候會看到又多了一筆 Build Details,狀態是 Building,而 Dockerfile 這個分頁也已經抓到我們剛剛 push 上去的 Dockerfile 了。
稍等一段時間,就會看到狀態已經是 Finished,點進去看,也有整個 build 的過程的 logs 可以看。
Part IV: pull image and test
最後,我們測試看看,把這個 image pull 下來用用看。
docker pull azole/docker-auto-build-test
docker run azole/docker-auto-build-test
Part V: 優化
這個 Dockerfile 其實還可以做更好的設計,例如:
- 將 ubuntu update 獨立成一個 image。
- 再從這個更新過的 image 去安裝 git,也獨立成一個 image。
- 接續 2 這個 image 去安裝 nodejs,然後這些都 push 上去。
- automated build 這邊的 Dockerfile 就從 3 做出來的 image 去 build。
於是 Dockerfile 就只剩下這些:
FROM azole/testbase
# pull
RUN git clone https://github.com/azole/docker-auto-build-test.git
WORKDIR /docker-auto-build-test
RUN npm install
# run test
CMD ["npm", "test"]
先把基礎環境做好,這就不用重複去 build 這些基礎的環境了,每次的 automated build 只需要從 pull 程式碼開始即可,image build 的速度會快上許多。
Part VI: 與 CI (Jenkins) 整合
目前在 Jenkins Plugins 已經可以找到幾個跟 docker 有關的 plugins,其中有一個 dockerhub plugin 看起來最符合這個實驗的情境,它可以搭配 dockerhub 的 webhooks,當 dockerhub build 好一個 image 時,通知 jenkins 去做一些事。
- 到 Jekins管理界面 -> 管理 Jenkins -> 管理外掛程式,切換到「可用的」,利用右上角的「過濾條件」搜尋 docker,就可以看到 dockerhub,勾選安裝。
- 建立 Jenkins 工作,在新增專案(或組態設定)的頁面,可以看到「建置觸發程序」裡頭多了一個「Run when a new image is built on DockerHub」,勾選起來,讓這個工作能接受來自於 dockerhub 的通知。
- 在建置的選項中,也可以看到多了一個「Pull Docker image from DockerHub」,在 Image ID 填上「azole/docker-auto-build-test」。每一個在步驟 2 有勾選「Run when a new image is built on DockerHub」的工作都會收到來自於 DockerHub 的通知,所以要設定這個 Image ID 來判斷是否是這個工作應該要處理的 dockerhub trigger。
- 現在來設定讓 DockerHub 發出通知。到 DockerHub 的網頁上,進入該 repo,網頁的右邊會有一個「Webhooks」,點選進去。按下「Add Webhook」,這邊輸入一個自己方便管理的名稱,然後在 URL1 的地方填「 http://[Jenkins Server]:8080/dockerhub-webhook/」,按下 save 後回到 Webhooks 的管理界面,可以看到剛剛新增的那組 webhook,有一個 Test 可以進行測試。
- 按下 Test 或執行 build 時,當 DockerHub 完成 build 的動作後,就會發送通知給 Jenkins,Jenkins 就能透過 DockerHub Plugin 來把這個新的 image pull 下來。
另外還有一個"Docker build step plugin",可以讓 jenkins 支援 docker 的命令:
- 到 Jekins管理界面 -> 管理 Jenkins -> 管理外掛程式,切換到「可用的」,利用右上角的「過濾條件」搜尋 docker,就可以看到 Docker build step plugin,勾選安裝。
- 安裝完這個 plugin 之後,請到 Jenkins -> 管理 Jenkins -> 設定系統 -> 找到 Docker Builder,這邊有一個 Docker URL 需要設定,填入 http://localhost:2375,這是連接 docker 的 remote REST API (必須先在 docker 啟動),設定完成後,可以利用 Test Connection 測試看看是否有成功。
- 建立 Jenkins 工作,在新增專案(或組態設定)的頁面,新增建置步驟的選項中,可以看到多了一個「Execute Docker container」的選項,選擇這個選項。
- 選擇 Docker Command,這裡可以看到這個 plugin 支援的 docker 命令,就看各位的需求是什麼。我這邊是要把 image pull 下來,所以選擇 pull image,在 Name of the image to pull (repository/image) 填入 azole/docker-auto-build-test,在 Registry Server Addresses 填入 registry.hub.docker.com。然後儲存這些設定。
- 按下「馬上建置」,就可以看到 Jenkins pull 一個 image 下來,這邊當然可以繼續做後續的動作,例如在 pull 下來後執行它。
當 DockerHub build 完後主動通知 Jenkins,Jenkins 透過 DockerHub Plugin 收到 trigger、也把 image pull 下來後,就可以透過 Docker build step plugin 來跑 container 或是做一些管理。
以上我們就完成了 push -> github -> dockerhub automated build -> jenkins pull images -> (run containers for test -> deploy) 的動作。
而 Docker build step plugin 支援的指令還不錯,也可以換個路徑嘗試,從 Jenkins 出發來控制這些,一如開頭提到的第二條路徑。
以上的範例是從無到有去建立,包括 github repo 與專案內容也是,步驟上可以視自己的情況去做,github repo, 專案內容, Dockerfile, docker hub repo 中只有 github repo 要先于 docker repo 建立,其他的順序都沒差。
補充:remote REST API 啟動方式
以 CentOS 來說,我是在 /etc/sysconfig/docker 這個檔案中加上
-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
重新啟動 docker,這樣就生效了。可以利用 curl localhost:2375/images/json 來進行測試。