背景

最近朋友有个项目代码托管用的码云,测试服务器(阿里云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
}

ci.sh

#!/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.sh

docker 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实践的更多相关文章

  1. 基于阿里云容器服务用docker容器运行ASP.NET 5示例程序

    小试阿里云容器服务 之后,接下来有一个挡不住的小试冲动--用docker容器运行程序.首先想到的程序是 ASP.NET 5示例程序,于是参考msdn博客中的这篇博文 Running ASP.NET 5 ...

  2. (二)基于阿里云的MQTT远程控制(购买阿里云,在云端安装MQTT,测试MQTT远程通信)

    QQ名称为Friday~的网友把他自己买MQTT的过程截图发给了我,今天就说一下如何购买阿里云,安装MQTT可以参考 http://www.cnblogs.com/yangfengwu/p/77646 ...

  3. .Net Core in Docker - 使用阿里云Codepipeline及阿里云容器镜像服务实现持续集成(CI)

    前面已经介绍过了 .Net Core 程序发布到 Docker 容器的内容.但是每次通过 SSH 链接到服务器敲命令,运行脚本也是挺麻烦的一件事.程序员是最懒的,能让电脑解决的问题绝不手动解决,如果当 ...

  4. 一·创建Linux服务器(基于阿里云)

    本系统是基于阿里云服务器,购买请前往https://www.aliyun.com/?spm=5176.8142029.388261.1.taXish ,由于经济能力的限制,本人购买的是最低配置如下 其 ...

  5. 基于阿里云ECS的phpwind网站备案前如何远程访问调试?

    基于阿里云ECS的phpwind网站部署非常方便,但云主机的外网IP绑定域名却比较复杂.先要申请域名,成功后还需要备案.尤其是企业网站备案,需要提交的资料较多,准备资料以及审批的时间较长.这段时间在外 ...

  6. 基于阿里云server搭建SVNserver

    基于阿里云server搭建SVNserver 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/ex_net/article/details/8577 ...

  7. 基于阿里云的JavaEE系统框架介绍

    基于阿里云的系统框架展望 1) CDN 用于缓存静态文件等等.七牛和阿里的都还可以. 七牛要做的久一点,各种图片处理的接口要完善一些 阿里的CDN要稍微好一点点,但是没有不安全的访问方式,访问稍微没有 ...

  8. 阿里云CodePipeline vs Jenkins

    产品概述_产品简介_CodePipeline-阿里云 https://help.aliyun.com/document_detail/56512.html CodePipeline管理控制台https ...

  9. Python3.6+nginx+uwsgi部署Django程序到阿里云Ubuntu16.04系统

    Python3.6+nginx+uwsgi部署Django程序到阿里云Ubuntu16.04系统 这个是写好的Django程序在本地机运行的情况,一个查询接口. 准备工作 1.首先购买一台阿里云的EC ...

随机推荐

  1. 真机调试报The executable was signed with invalid entitlements.错误

    真机运行时,提示The executable was signed with invalid entitlements.(The entitlements specified in your appl ...

  2. springmvc 简化Javaweb 简单应用

    第一步 : 导入外部jar包,放在如图目录下 第二步:简单配置web.xml 文件 <?xml version="1.0" encoding="UTF-8" ...

  3. pymysql总结

    一.创建数据库 import pymysql conn = pymysql.connect(host='ip', user='root', password='密码') # 以字典的形式返回操作结果 ...

  4. python3默认参数陷阱

    默认参数的值是容器类型,每次调用函数的时候,如果不传值,会用公用资源池 def func(k, v=[]): v.append(k) print(v) func('wt') func('ab', [] ...

  5. scrapy在存储数据到json文件中时,中文变成为\u开头的字符串的处理方法

    在settings.py文件中添加 FEED_EXPORT_ENCODING = 'utf-8'

  6. JsonResponse和HttpResponse

    1.联系 JsonResponse继承HttpResponse 2.区别 JsonResponse 数据类型装自动换成json字符串并相应到前端,传到前端的是数据类型而非json字符串 HttpRes ...

  7. python property()函数:定义属性

    正常情况下,类包含的属性应该是隐藏的,只允许通过类提供的方法来间接的实现对类属性的访问和操作. class Person: #构造函数 def __init__(self, name): self.n ...

  8. 高通量计算框架HTCondor(一)——概述

    目录 1. 正文 2. 目录 3. 参考 4. 相关 1. 正文 HTCondor是威斯康星大学麦迪逊分校构建的分布式计算软件和相关技术,用来处理高通量计算(High Throughput Compu ...

  9. 【javaScript】获取某年某月的的最后一天(即当月天数) 妙用

    javaScript里 面的new Date("xxxx/xx/xx")这个日期的构造方法有一个妙处,当你传入的是"xxxx/xx/0"(0号)的话,得到的日期 ...

  10. 利用http协议使用普通的网站虚拟主机+安信可A6C GPRS模块实现对stm32的远程升级

    步骤: 1.生成bin文件并将bin文件放到虚拟主机目录内 2.做一个php的页面分块读取该bin文件,以asc字符echo出来,并标记好头尾长度和校验. 3.GPRS协议栈连接主机路径,收到内容,将 ...