基於 Gitlab 交付 Go 程式的 Docker 映象

荊全齊發表於2017-12-13

Gitlab 提供了完整 CI/CD 功能並且整合了 docker 映象服務, 可以在此基礎上快速實現 docker 映象交付.

樣例工程目錄結構如下github.com/dodocat/git…:

├── .gitlab-ci.yml
├── Dockerfile
├── Gopkg.lock
├── Gopkg.toml
├── README.md
├── app.conf
├── main.go
└── vendor
複製程式碼

依賴管理

專案使用 golang 官方包管理工具 dep 進行依賴管理, 參考官方文件: github.com/golang/dep

直接通過 go get 安裝 dep

go get -u github.com/golang/dep/cmd/dep
複製程式碼

記得設定環境變數

export PATH=$PATH:$GOPATH/bin
複製程式碼

在工程根目錄初始 dep

dep init
複製程式碼

執行之後會生成 Gopkg.toml Gopkg.lock vendor/ 這三檔案都需要 commit 進入版本管理系統. 所有的依賴檔案都在 vendor/ 目錄裡. 詳細資訊參閱 dep 文件. 新增新庫或者更新了已有庫導致 vendor 目錄變更, 需要將變更 commit 進入版本管理裡.

Gitlab CI 配置

CI 配置了三個階段 test build deploy, 配置了 before_script 在每個任務執行前初始 Go 的相關環境變數.

在 test 階段執行單元測試

在 build 階段將 Go 程式編譯成單體二進位制檔案, 並作為 artifact 儲存, 用於其他階段的任務使用.

在 deploy 階段將編譯的結果打包成 docker 映象, 併發布到 registry.

CI 配置檔案 .gitlab-ci.yml 內容如下

image: docker:git

stages:
  - test
  - build
  - deploy

build-dev:
  stage: build
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build --build-arg APP_ROOT=/go/src/$CI_PROJECT_NAME -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME -f docker/test/Dockerfile .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
  only:
    - develop
 
deploy-dev:
  stage: deploy
  variables:
    DOCKER_HOST: $DOCKER_HOST_DEV
    DOCKER_TLS_VERIFY: 1
    SERVICE_NAME: dev
  image: docker:latest
  script:
    - mkdir -p ~/.docker
    - echo "$DOCKER_HOST_TLS_CA_CERT_DEV" > ~/.docker/ca.pem
    - echo "$DOCKER_HOST_TLS_CERT_DEV" > ~/.docker/cert.pem
    - echo "$DOCKER_HOST_TLS_KEY_DEV" > ~/.docker/key.pem
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker service update --with-registry-auth --image $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME $TEST_SERVICE_NAME
  environment:
    name: dev
    url: http://${CI_BUILD_REF_NAME}.project.example.com
  only:
    - dev
複製程式碼

Dockerfile

編寫 Dockerfile:

FROM golang:1.9.0
ARG  APP_ROOT
WORKDIR ${APP_ROOT}
COPY ./ ${APP_ROOT}
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

FROM alpine:latest  
ARG APP_ROOT
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app/
RUN mkdir -p ./conf/dev && touch ./conf/dev/app.conf
COPY --from=0 ${APP_ROOT}/main .
COPY --from=0 ${APP_ROOT}/conf/app.conf ./conf/app.conf
ENV DREAMENV TEST
ENV DEPLOY_TYPE DOCKER
ENTRYPOINT ["/app/main"]
複製程式碼

Gitlab registry

Gitlab 內整合了 registry 可以為所有專案提供 docker 映象服務.

go build -o main
docker login # 輸入使用者名稱密碼登陸
docker built -t registry.gitlab.example.com/group/project -f Dockerfile . # 編譯 Docker 映象
docker push registry.gitlab.example.com/group/project # 把 docker 映象釋出到 gitlab registry
複製程式碼

本地測試docker環境編譯執行:

go build -o main
docker build -t gitlab-go-docker-demo docker/test/Dockerfile .
docker run gitlab-go-docker-demo
複製程式碼

部署

在伺服器上登陸 docker registry:

docker login registry.gitlab.example.com
複製程式碼

登陸成功後拉取 docker 映象:

# 以測試伺服器為例, 正式伺服器需指定相應版本
docker pull registry.gitlab.examlple.com/group/project/test:latest
複製程式碼

執行:

docker run -p 80:80 -v /var/log/:/app/log/ --restart unless-stopped registry.gitlab.example.com/group/project/test
複製程式碼

參考閱讀

  • https://github.com/golang/dep

  • https://docs.gitlab.com/ce/ci/docker/using_docker_build.html 詳解了如何配置 gitlab-ci docker 構建

  • https://about.gitlab.com/2016/05/23/gitlab-container-registry/ 介紹了關於 gitlab container registry 的使用

  • https://blog.stackahoy.io/a-guide-to-automated-docker-deployments-w-gitlab-ci-510966dd6022 雲服務商 stackahoy.io 關於 go 的部署教程

  • https://docs.gitlab.com/ee/ci/yaml/

  • https://docs.gitlab.com/ee/ci/variables/README.html

相關文章