funcmain() { // use PORT environment variable, or default to 8080
port := "8080"if fromEnv := os.Getenv("PORT"); fromEnv != "" {
port = fromEnv
}
http.HandleFunc("/version", showVersion)
http.HandleFunc("/", sayHello)
log.Println("Listen server on " + port + " port") if err := http.ListenAndServe(":"+port, nil); err != nil {
log.Fatal(err)
}
}
從上面程式可以看到,在編譯 Go 語言專案時,可以從外部帶入 version 變數,證明目前的 App 版本。請參考 Makefile 內的
build:
ifneq ($(DRONE_TAG),)
go build -v -ldflags "-X main.version=$(DRONE_TAG)" -a -o release/linux/amd64/hello else
go build -v -ldflags "-X main.version=$(DRONE_COMMIT)" -a -o release/linux/amd64/hello
endif
apiVersion: extensions/v1beta1
kind: Deploymentmetadata:
name: frontend # these labels can be applied automatically# from the labels in the pod template if not set
labels:
app: gotraining
tier: frontend spec:# this replicas value is default# modify it according to your case
replicas: 3 # selector can be applied automatically# from the labels in the pod template if not set# selector:# app: guestbook# tier: frontend
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds: 5
template:
metadata:
labels:
app: gotraining
tier: frontend
spec:
containers:
- name: go-hello
image: appleboy/golang-http:VERSION
imagePullPolicy: Always
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 8080
env:
- name: FOR_GODS_SAKE_PLEASE_REDEPLOY
value: 'THIS_STRING_IS_REPLACED_DURING_BUILD'
大家可以找到 image: appleboy/golang-http:VERSION,這邊需要寫個 sed 指令來取代 VERSION,部署到 staging 則是 latest,如果是 tag 則取代為 DRONE_TAG
ifneq ($(DRONE_TAG),)
VERSION ?= $(DRONE_TAG) else
VERSION ?= latest
endif
prepare:
sed -ie "s/VERSION/$(VERSION)/g" deployment.yml
prepare:
sed -ie "s/VERSION/$(VERSION)/g" deployment.yml
sed -ie "s/THIS_STRING_IS_REPLACED_DURING_BUILD/$(shell date)/g" deployment.yml
cat deployment.yml
而 Tag 就不用擔心,原因就是 VERSION 就會改變不一樣的值,所以肯定會即時更新,那假設團隊想要上傳相同 tag (這是不好的做法,請盡量不要使用),這時候動態修改 env 的作法就發揮功效了。從上面的教學,現在我們看安新的透過 GitHub Flow 來完成部署 Staging 及 Production 了。