docker+jenkins+golang持續集成實踐[轉載自個人博客]

博客地址:yeqown.github.comgit


原由

由於生產須要最近又從新折騰了一下Jenkins和docker。主要目的是想自動編譯,打包,部署一些Golang的HttpServer。因而決定使用Jenkins來作這個持續集成的載體,選擇Jenkins出於兩點緣由:github

1. 之前就使用過,上手會更快
2. 社區比較成熟,插件和文檔豐富golang


安裝Docker和Pull Jenkins鏡像

這一步,做爲前置條件且不是本文主要要描述的步驟,所以略去。網上也有不少參考資料~docker


Jenkins & docker-compose配置

爲了方便我才用了docker-compose這個工具,docker-compose 基礎能夠參見個人docker-compose上手。這裏直接上配置:ssh

version: '2'

services:
  jenkins:
    container_name: jenkins-lts
    ports:
      - 9001:8080
      - 50000:50000
    image: jenkins/jenkins:lts
    volumes:
      - /home/worker/jenkins/jenkins_home:/var/jenkins_home

配置也是官方的示例配置。工具

Note: 將宿主機的/home/worker/jenkins/jenkins_home掛載爲容器的/var/jenkins_home目錄。這樣作的目的是,若是容器被不當心刪除也不至於Jenkins的數據丟失。

到這裏,咱們只須要執行docker-compose up -d即可以將Jenkins容器跑起來了,再配置一下Nginx,即可以直接訪問到Jenkins頁面了,並進行初始化。ui

個人目錄結構以下:this

➜  jenkins ll
total 8.0K
-rw-rw-r--  1 worker worker  220 May  2 17:19 docker-compose.yml
drwxrwxr-x 19 worker worker 4.0K May  3 15:53 jenkins_home
➜  jenkins pwd
/home/worker/jenkins
➜  jenkins docker-compose up -d # 運行

Publish Over SSH配置

Publish Over SSH配置,因爲咱們是經過docker運行的Jenkins,所以要特別配置一下SSH,方便Jenkins部署項目。這裏先列出步驟:插件

  1. 安裝Publish Over SSH
  2. 容器內ssh-keygen
  3. 配置Publish Over SSH
  4. 配置Git倉庫部署公鑰 #這一步至關於拉取代碼的Credentials

Golang Build-env

由於默認的Jenkins鏡像是不帶有Go的編譯工具的,因此咱們頗有必要安裝一個Go插件Go-Plugin-Jenkins
具體步驟以下:rest

  1. 安裝JenkinsGo插件
  2. 在全局工具配置中,安裝Go
  3. 在對應任務配置-> 構建環境項,選擇Go版本

這一步的詳細步驟能夠在參考文獻第一條中查詢Setup Go Build Environment

Note: 官方文檔中說全局配置Go是在系統設置中進行的,可是我用的 Jenkins ver. 2.107.2,這一項配置是在全局工具配置中。

如何打包部署

編寫一個makefile來打包項目,經過scp來分發部署服務,這也是配置Publish Over SSH的目的。

因爲Jenkins鏡像不帶有make相關工具(甚至Vim也沒有),因此須要安裝Make及其相關工具。與此同時,若是項目使用了相關的依賴管理工具,所以還有必要去配置相關的GO環境變量。其中Go的安裝路徑在:
/var/jenkins_home/tools/org.jenkinsci.plugins.golang.GolangInstallation/$GOVERSION中。

這裏貼上個人Makefile

# To test, build, deploy offline-tasks
#   -: ignore this commnad error
#   @: no display current commnad to std output

# Commnads declare
GOCMD=go
GOTEST=$(GOCMD) test
GOBUILD=$(GOCMD) build

# Params define
MAIN_PATH=../main
PACKAGE_PATH=../package
PACKAGE_BIN_PATH=../package/bin
BIN=offline-tasks
FILENAME=offline-tasks.tar.gz

# Deploy Params
DEV_HOST=zy-dev
DEV_TAR_PATH=/home/worker/project/offline-tasks

PROD_HOST=zy-pro2
PROD_TAR_PATH=/home/worker/project/offline-tasks

default: build pack

test: 
  # testing
  - $(GOTEST) ../... -v

build: 
  # building
  mkdir $(PACKAGE_PATH)
  mkdir $(PACKAGE_BIN_PATH)
  cd $(MAIN_PATH) && $(GOBUILD) -o $(BIN) 
  mv "$(MAIN_PATH)/$(BIN)" $(PACKAGE_BIN_PATH)
  cp -r "../configs" $(PACKAGE_PATH)
  cp "../sh/start.sh" $(PACKAGE_BIN_PATH)

pack:
  # packing
  cd $(PACKAGE_PATH) && tar -zcvf ../$(FILENAME) ./*
  mv ../$(FILENAME) $(PACKAGE_PATH)


##################################################
#                                                #
#   deploy:         from zy-dev to execute       #
#   deploy-dev:     from dev-CI to execute       #
#   deploy-prod:    from prod-CI to execute      #
#                                                #
##################################################

deploy: clean build pack
  # deploy dev from dev
  cp $(PACKAGE_PATH)/$(FILENAME) $(DEV_TAR_PATH)
  cd $(DEV_TAR_PATH) && tar zxvf $(FILENAME) && supervisorctl -c configs/dev.supervisord.conf restart offline-tasks

deploy-dev: clean build pack
  # deploy-dev from CI
  scp $(PACKAGE_PATH)/$(FILENAME) $(DEV_HOST):$(DEV_TAR_PATH)
  ssh $(DEV_HOST) "cd $(DEV_TAR_PATH) && tar zxvf $(FILENAME) && supervisorctl -c configs/dev.supervisord.conf restart offline-tasks"

deploy-prod: clean build pack
  # deploying prod from dev or CI
  scp $(PACKAGE_PATH)/$(FILENAME) $(PROD_HOST):$(PROD_TAR_PATH)
  ssh $(PROD_HOST) "cd $(PROD_TAR_PATH) && tar zxvf $(FILENAME) && supervisorctl -c configs/prod.supervisord.conf restart offline-tasks"

clean:
  # cleaning
  rm -fr $(PACKAGE_PATH)
  rm -fr ../$(FILENAME)

總結

進過上述的一系列操做以後,只剩下一個比較尷尬的問題了:若是Go代碼倉庫中vendor不帶有依賴項目,那麼獲取依賴的動做就要本身手動來操做了~。或許能夠在makefile中新增一個deps,以下:

# default set $CURDIR="$PROJ_ROOT/sh"
# preparing works...
GVT_RESTORE=gvt restore
PROJ_ROOT=../

deps:
  cd ($PROJ_ROOT) && $(GVT_RESTORE)

build: deps
  # building
  mkdir $(PACKAGE_PATH)
  mkdir $(PACKAGE_BIN_PATH)
  cd $(MAIN_PATH) && $(GOBUILD) -o $(BIN) 
  mv "$(MAIN_PATH)/$(BIN)" $(PACKAGE_BIN_PATH)
  cp -r "../configs" $(PACKAGE_PATH)
  cp "../sh/start.sh" $(PACKAGE_BIN_PATH)
# other commands...

而且加deps命令,加build命令中,每次打包都檢查一下依賴。


參考資料

相關文章
相關標籤/搜索