首先我們要先準備一份 code
(以 golang 示範) 跟一份 Dockerfile
檔案,稍後將由 Drone
自動將程式 build
成 Image
// main.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, "Hello World")
})
r.Run() // listen and serve on 0.0.0.0:8080
}
## Dockerfile
# 第一層基底
FROM golang:1.11.2-alpine AS build
# 複製原始碼
COPY . /go/src/Project
WORKDIR /go/src/Project
# 進行編譯(名稱為:project)
RUN go build -o project
# 最終運行golang 的基底
FROM alpine
COPY --from=build /go/src/Project/project /app/project
WORKDIR /app
ENTRYPOINT [ "./project" ]
首先準備好以上範例,接著我們準備來執行昨天的四個步驟:
Dockerfile
並 build
成映像檔Harbor
私有庫Drone
啟動專案)完成以下 yaml
後,執行 git push
將會觸發 drone
執行 clone 事件
## Drone 1.0 版本寫法
kind: pipeline
type: docker # 在 Docker 內部執行管道命令
name: clone # 可自行定義的名稱
以 golang
來說,若不將程式內有用到的 pkg
一併上傳至 gitlab
等平台,那麼每次在 build images
之前,就必須要先將使用到的 pkg
重新對外在拉一次,因此這部份也可以交給 drone
自動完成。
## Drone 1.0 版本寫法
kind: pipeline
type: docker # 在 Docker 內部執行管道命令
name: clone # 可自行定義的名稱
steps:
- name: build-golang # 事件一:可自行定義的名稱
image: neil605164/plugin-govendor # 使用 neil605164/plugin-govendor 容器
commands: # 需執行的指令
- mkdir -p /usr/local/go/src/${DRONE_REPO_NAME} # 於 goroot 建立專案名稱的空資料夾
- ls -al vendor # 查看當前 vendor 資料夾(尚未編譯完成的 code)
- rsync -r /drone/src/* /usr/local/go/src/${DRONE_REPO_NAME} # 將 clone 的專案複製到 goroot 底下
- cd /usr/local/go/src/${DRONE_REPO_NAME} # 移動至 goroot 專案底下
- govendor sync # 編譯 golang 程式碼
- rsync -r /usr/local/go/src/${DRONE_REPO_NAME}/* /drone/src # 將編譯後的程式在複製回 drone 預設 path
- ls -al vendor # 查看當前 vendor 資料夾(已經編譯完成的 code)
當 Drone
編譯程式碼時,會自動至外部 clone
有用到的 pkg
,當編譯完成後,所有有用到的 pkg
都會被放置 vendor
資料夾底下,如下圖所示:
備註:
步驟二當中使用到的 neil605164/plugin-govendor
就是我是先封裝好的 drone plugin
, 以下是 neil605164/plugin-govendor
的 Dockerfile
# 基底
FROM golang:1.11.2-alpine
# 安裝 git + rsync
RUN apk add git rsync
# 安裝 govendor
RUN go get -u github.com/kardianos/govendor
Dockerfile
並 build
成映像檔 + 推至 Harbor 私有庫當程式編譯完成後,當然就是要推到私有庫上啦,在這邊直接採用官方 plugins/docker
,這一個現成的 plugin
就已經夠方便啦,不僅自動 build image
還可以自動推到指定的私有庫,若真的不適合的話也可以透過原本作者寫的在往上疊加自己要的功能上去就好。
## Drone 1.0 版本寫法
kind: pipeline
type: docker # 在 Docker 內部執行管道命令
name: clone # 可自行定義的名稱
steps:
- name: build-golang # 事件一:可自行定義的名稱
image: neil605164/plugin-govendor # 使用 neil605164/plugin-govendor 容器
commands: # 需執行的指令
- mkdir -p /usr/local/go/src/${DRONE_REPO_NAME} # 於 goroot 建立專案名稱的空資料夾
- ls -al vendor # 查看當前 vendor 資料夾(尚未編譯完成的 code)
- rsync -r /drone/src/* /usr/local/go/src/${DRONE_REPO_NAME} # 將 clone 的專案複製到 goroot 底下
- cd /usr/local/go/src/${DRONE_REPO_NAME} # 移動至 goroot 專案底下
- govendor sync # 編譯 golang 程式碼
- rsync -r /usr/local/go/src/${DRONE_REPO_NAME}/* /drone/src # 將編譯後的程式在複製回 drone 預設 path
- ls -al vendor # 查看當前 vendor 資料夾(已經編譯完成的 code)
- name: build-image-push-harbor # 事件二:可自行定義的名稱
image: plugins/docker # 使用 plugins/docker 容器
settings:
username: # harbor 私有庫帳號
from_secret: docker_username
password: # harbor 私有庫密碼
from_secret: docker_password
repo: <harbor url> /library/golang-hello # harbor 私有庫存放位置
tags: latest # harbor image tag( 也可以利用 ${DRONE_TAG} 自動取得 push 到 gitlab 的版號)
registry: <harbor url> # harbor 私有庫網址
今天就是範到這邊啦,以上步驟就完成了透過 drone
自動「編譯程式碼」、「build image」、「push image」三個動做,這樣是不是只需要寫一次發布腳本,接下來的流程每次都由 drone
自動完成。