内容简介:最近朋友有个项目代码托管用的码云,测试服务器(阿里云ECS)只有一台,三四个人开发,于是想基于阿里云的阿里云CodePipeline是兼容Jenkins标准的、提供快速可靠的持续集成与持续交付服务。基于容器技术和阿里云基础服务架构,提供稳定和安全的代码/Docker编译构建,测试,扫描和部署的工具服务,并提供Pipeline As Code的编码级配置模式,满足应用程序和基础设施快速可靠的交付和更新。
背景
最近朋友有个项目代码托管用的码云,测试服务器(阿里云ECS)只有一台,三四个人开发,于是想基于阿里云的 CodePipeline 快速打造一套自动化cicd的流程,使用 docker 来进行多套环境部署。
CodePipeline 介绍
阿里云CodePipeline是兼容Jenkins标准的、提供快速可靠的持续集成与持续交付服务。基于容器技术和阿里云基础服务架构,提供稳定和安全的代码/Docker编译构建,测试,扫描和部署的 工具 服务,并提供Pipeline As Code的编码级配置模式,满足应用程序和基础设施快速可靠的交付和更新。
上面是阿里云的官方介绍,兼容jekins的标准,一次无意的点击出现了下图的图标,感觉就是jenkins的基础上做了一次二次开发。
新建构建项目
构建项目基本配置
基本信息配置
由于项目使用到了一些国外的lib,当然选择国内的节点也是可以的,不过在写Dockerfile的时候记得加上代理。
源码管理配置
选择合适的代码仓库,也可以是私仓,不过需要配上自己的账号和ssh key相关信息。
构建配置
我这里使用的是阿里云的私有的镜像仓库基于Dockerfile来构建镜像,注意配置凭证。
项目目录
gin_demo ├── app │ └── app.go ├── conf │ └── app.ini ├── Dockerfile ├── docs │ └── sql │ └── mjs.sql ├── go.mod ├── go.sum ├── main.go ├── middleware │ ├── jwt │ │ └── jwt.go │ └── logging │ └── logger.go ├── mjs.exe ├── models │ ├── mongo │ │ └── db.go │ └── mysql │ ├── db.go │ ├── teacher.go │ └── user.go ├── pkg │ ├── app │ │ ├── form.go │ │ ├── request.go │ │ └── response.go │ ├── def │ │ └── def.go │ ├── e │ │ ├── code.go │ │ ├── def.go │ │ └── msg.go │ ├── file │ │ └── file.go │ ├── gredis │ │ └── redis.go │ ├── logging │ │ ├── file.go │ │ └── log.go │ ├── setting │ │ └── setting.go │ ├── upload │ │ └── image.go │ └── util │ ├── jwt.go │ ├── md5.go │ ├── pagination.go │ └── util.go ├── README.en.md ├── README.md ├── routers │ ├── api │ │ └── v1 │ └── router.go ├── runtime │ └── logs │ ├── log20190528.log │ └── log20190529.log └── service ├── teacher_service │ └── teacher.go └── user_service └── user.go
Dockerfile
FROM golang:1.12.4 as build #ENV GOPROXY https://goproxy.io WORKDIR /go/cache ADD go.mod . ADD go.sum . RUN go mod download WORKDIR /go/release ADD . . RUN GOOS=linux CGO_ENABLED=0 go build -ldflags="-s -w" -installsuffix cgo -o gin_demo main.go FROM scratch as prod COPY --from=build /usr/share/zoneinfo/Asia/Shanghai /etc/localtime COPY --from=build /go/release/gin_demo / COPY --from=build /go/release/conf ./conf CMD ["/gin_demo"]
注:如果选择国内节点构建必须配上代理 ENV GOPROXY https://goproxy.io
配置触发器
这里选择一个构建的代码分支,然后点击生成,将生成后的url可以在对应的代码仓库配上webhook之类的配置。选择合适的触发方式。
配置部署
阿里云构建步骤里面部署到ECS上(不方便)和部署到k8s(收费)都不能满足项目场景需求,不过上面支持 shell 脚本,于是自己想在朋友的那台阿里云ECS上跑个ci的web server,这里构建完之后就去通知下这个接口,然后去执行一些docker指令的脚本,拉取构建完之后的镜像并且重新启动,启动完之后邮件通知。于是写了这样一个很简单的web server。
main
package main import ( "fmt" "log" "net/http" "os/exec" "path" ) /* * @Author:hanyajun * @Date:2019/5/28 16:44 * @Name:ci_tools * @Function: ci 工具 */ // func HandleCi(w http.ResponseWriter, req *http.Request) { user := path.Base(req.URL.Path) //针对不同开发人员的push拉取不同的镜像和映射不同的端口 var port string switch user { case "zhangsan": port = "8088" case "lisi": port = "8087" case "wangmazi": port = "8086" case "dev": port = "8085" case "master": port = "8084" } println(user) result := Run(user,port) client:=NewMailClient("smtp.qq.com",465,"******@qq.com","*********")//注意使用465 ssl发送,25端口阿里云ecs禁止了。 s:=&SendObject{ ToMails:[]string{"******@qq.com","******@qq.com","******@qq.com"}, CcMails:[]string{"******@qq.com"}, Object:"cicd流程结果通知", ContentType:"text/html", Content:user+" has push something to the branch: "+user+"\n"+"result: "+string(result), } err:=client.SendMail(s) if err!=nil{ println("send mail fail",err) } _, _ = w.Write(result) } func main() { http.HandleFunc("/ci/", HandleCi) err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("ListenAndServe: ", err) } } func Run(user string,port string) []byte { shellPath := "/root/ci/ci.sh" command := exec.Command(shellPath, user,port) err := command.Start() if nil != err { fmt.Println(err) return []byte(err.Error()) } fmt.Println("Process PID:", command.Process.Pid) err = command.Wait() //等待执行完成 if nil != err { fmt.Println(err) return []byte(err.Error()) } fmt.Println("ProcessState PID:", command.ProcessState.Pid()) return []byte("success") }
mail.go
package main import ( "fmt" "gopkg.in/gomail.v2" ) /* * @Author:15815 * @Date:2019/5/8 17:47 * @Name:mail * @Function:邮件发送 */ type Client struct { Host string Port int Mail string Password string } type SendObject struct { ToMails []string CcMails []string Object string ContentType string Content string } func NewMailClient(host string, port int, sendMail, password string) *Client { return &Client{ Host: host, Port: port, Mail: sendMail, Password: password, } } func (m *Client) SendMail(s *SendObject) error { mgs := gomail.NewMessage() mgs.SetHeader("From", m.Mail) mgs.SetHeader("To", s.ToMails...) mgs.SetHeader("Cc", s.CcMails...) mgs.SetHeader("Subject", s.Object) mgs.SetBody(s.ContentType, s.Content) d := gomail.NewDialer(m.Host, m.Port, m.Mail, m.Password) if err := d.DialAndSend(mgs); err != nil { fmt.Printf("send mail err:%v", err) return err } return nil }
#!/bin/bash funCiTools() { docker pull registry.cn-shanghai.aliyuncs.com/***/***:$1 docker rm -f $1 docker run -d -p $2:8000 --name $1 registry.cn-shanghai.aliyuncs.com/***/***:$1 } funCiTools $1 $2
第一个参数是对应开发人员启动容器的名字以及构建镜像的tag和上面构建的配置一致,第二个参数是映射的端口。
构建ci_web_server
自己的电脑是windows的,朋友的阿里云ecs上又没有 go 环境,想构建基于 linux 的二进制程序,于是直接利用docker image 来构建了镜像,一个指令解决问题。
build.shdocker run --rm -i -v `pwd`:/go/src/ci -w /go/src/ci golang:1.11.5 go build -o ci ci
使用nohup直接将ci server放置后台运行。
nohup ./ci >output 2>&1 &
效果测试
直接修改点东西提交代码后就等邮件通知了,是不是感觉很爽。
提交完代码后就开始触发构建了。
最后构建完完成后触发ci server 进行deploy,完成邮件通知。
登录到阿里云Ecs上我们发现我们的容器已经启动成功了。
以上所述就是小编给大家介绍的《go程序基于阿里云CodePipeline的一次devops实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 小程序优化实践
- 小程序webview应用实践
- 微信小程序WebSocket实践
- 编程日历小程序,对小程序云开发和生成海报的实践
- 给小程序再减重 30% 的秘密(京喜小程序首页瘦身实践)
- 程序员必备,“向上管理” 实践指南
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。