背景
目前工作开发流程代码编译阶段,是各个开发自行在本地进行编译打包。
新来的同事抱怨说,当初搞定编译环境折腾了很久,申请云服务器的系统版本不一致,GCC
版本也做了升级,导致无法编译,因为安全性问题GCC
也无法降级,存在着个人环境搭建困难;有几次也遇到了同事将测试环境部分代码发布到生产环境的情况,无法知道编译的这个版本包含了哪些改动,尽管现在已经保持了git
代码和生产环境代码一致,也会因为个人的不规范导致额外的版本发布风险。
因此,抱着学习的态度,探索了一条CI/CD
标准化代码发布部署流程。
工具列表
下面是涉及到的工具
-
git仓库
-
镜像仓库
-
蓝盾流水线
-
docker:24.0.4
-
docker compose:v2.19.1
-
watchtower

前期准备
Dockerfile
制作golang项目的镜像包,需要将其提交到项目的根目录下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
FROM ubuntu:18.04 AS builder
COPY . /src
WORKDIR /src
ARG GOPROXY
ARG GOPRIVATE
ARG GOSUMDB
ENV PATH=$PATH:/usr/local/go/bin \
HOME=/root \
GOPROXY=${GOPROXY} \
GOPRIVATE=${GOPRIVATE} \
GOSUMDB=${GOSUMDB} \
GOROOT=/usr/local/go \
GOPATH=${HOME}/go \
GOBIN=${HOME}/go/bin
RUN apt-get update \
&& apt-get install gcc-4.8 g++-4.8 wget -y \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 40 \
&& wget https://go.dev/dl/go1.18.1.linux-amd64.tar.gz \
&& tar -C /usr/local -xzf go1.18.1.linux-amd64.tar.gz \
&& go build -o ./bin/AppMain .
FROM ubuntu:18.04
COPY --from=builder /src/bin /app/bin
COPY --from=builder /src/conf /app/conf
WORKDIR /app/bin
# 设置时区
RUN apt update \
&& apt install tzdata \
&& apt-get install -y ca-certificates \
&& chmod +x ./AppMain
ENV TZ=Asia/Shanghai
ENTRYPOINT ["./AppMain"]
|
watchtower启动配置文件
将会每120秒检测一次镜像版本是否有更新
1
2
3
4
5
6
7
8
9
10
|
version: '3'
services:
watchtower:
image: containrrr/watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/.docker/config.json:/config.json
command: --interval 120 --label-enable --cleanup
network_mode: host
|
启动命令
AppMain启动配置文件
watchtower
将会检测携带com.centurylinklabs.watchtower.enable
标签的容器
1
2
3
4
5
6
7
8
9
10
11
12
13
|
version: '3'
services:
inner:
#需要填写实际的仓库名
image: AppMain_image:latest
restart: always
volumes:
- $PWD/conf:/app/conf
- $PWD/logs:/app/logs
network_mode: host
labels:
- com.centurylinklabs.watchtower.enable=true
|
启动命令
测试环境最佳实践
测试环境不需要设置的太过严格,提交git时注意做好提示说明。
创建开发代码分支版本
1
|
git checkout -b feature
|
在蓝盾创建测试流水线
设置分支有代码提交则编译打包最新镜像,不需要审核流程。
生产环境最佳实践
保持master
分支是最新代码
将开发分支代码合并到主分支
1
2
3
|
A - B - C - D - E (main)
\
F - G - H (feature)
|
只合并某个commit
这里的 是你想要合并的那个提交的哈希值。
1
|
git cherry-pick <commit-hash>
|
将某个提交之前的所有提交合并到主分支
这里的 <F-hash>
是提交 F 的哈希值,<G-hash>
是提交 G 的哈希值。<F-hash>
^ 表示 F 的父提交。
1
|
git cherry-pick <F-hash>^..<G-hash>
|
合并分支中特定文件的更改
这里的 <feature-branch>
是你想要提取更改的分支名称,<path-to-file>
是你想要提取的文件路径。
1
|
git checkout <feature-branch> -- <path-to-file>
|
需要再次执行commit命令。
在蓝盾创建生产流水线
-
触发方式设置为Releases
,或者手动执行。
-
增加人员审核流程。
-
打包为两个镜像,用于灰度和全量。
FAQ
如何确保docker不会崩溃
1
2
3
4
5
6
7
|
#通过配置 systemd 服务文件,可以确保 Docker 守护进程在失败后自动重启。
sudo systemctl edit docker
#添加以下内容:
[Service]
Restart=always
RestartSec=5
|
如何实现灰度发布
流水线分阶段打包两个镜像,一个用于灰度机器使用,一个用于全量机器使用。
如何快速回滚
在每次流水线构建时增加构建号标识,通过镜像转存插件快速将上一版本设置为最新版本镜像。