背景

最近朋友有个项目代码托管用的码云,测试服务器(阿里云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. 1.异常(Error和Exception)

    什么是异常 比如上午我们一般是开车去上班,正常情况下,一般都不会迟到,但是今天突然有个问题,车坏了或者限行了,于是乎你改坐公交了,就有可能会迟到,这就属于一种异常的情况.在实际生活中呢,可能会遇到很多 ...

  2. 可视化限流管理,Sentinel 控制台启动和接入

    Sentinel 的使用可以分为核心库和控制台两个部分. 核心库不依赖任何框架/库,集成了主流框架,可以进行单机限流降级等功能, 控制台Dashboard提供了可视化的管理限流规则.对集群进行监控,集 ...

  3. Dynamics CRM CE 怎样从 UCI 改为 classic UI

    dynamics 现在大力推UCI. 但是对于大部分人来说还是使用不习惯. 怎样从UCI改为classic UI呢 1. 快速的方法 https://xxx.crm.dynamics.com/main ...

  4. Qt常用UI控件读取、写入方法

    本文用途:快速备忘,方便调用,写熟了自然就记下了. [1.标签label] 读取:ui->label->text() 写入:ui->label->setText("p ...

  5. nginx白名单黑名单设置

    nginx白名单黑名单设置 白名单设置,访问根目录 location / { allow 123.34.22.155; allow 33.56.32.1/100; deny all; } 黑名单设置, ...

  6. 自定义BeanDefinitionRegistryPostProcessor注册bean

    自定义BeanDefinitionRegistryPostProcessor 概述 BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProce ...

  7. 降级gcc版本

    前言 ubuntu16.04版本中默认的gcc版本是5.4,因为有些第三方应用依赖的问题,我不得不降级到5.3,下面是关于gcc的降级操作 部署操作 下载GCC源码(https://ftp.gnu.o ...

  8. 七、django学习之聚合函数

    七.django学习之聚合函数 如何使用 from django.db.models import Avg,Max,Min,Sum models.Book.objects.all().aggregat ...

  9. java编写杨辉三角

    import java.util.Scanner; /* *计算杨辉三角: * 规律:两边都是1 * 从第三行开始,上一行的前一个元素+与其并排的元素等于下面的元素 * 例如: * 1 * 11 * ...

  10. Lighthouse

    北大程郁缀教授: 一,"日月之行,若出其中,星汉灿烂,若出其里."要找机会去感受大海,男人要有大海一样的胸怀,大气者方能成大器. 二,"亦余心之所善兮,虽九死其而未悔.& ...