github-webhook+docker实现项目可持续自动化部署

这篇具有很好参考价值的文章主要介绍了github-webhook+docker实现项目可持续自动化部署。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用nginx+pm2+github-webhook+docker实现项目自动部署

注:docker也能实现pm2的守护进程功能(持续启动项目),所以使用了docker就不需要使用pm2了

但是需要注意的是使用node启动的webhook服务器不能使用docker,因为在webhook内部的sh脚本执行时需要到服务器的前后端项目文件中去执行,如果对webhook使用了docker,那么webhook所在的docker内不会存在前后端项目文件,所以webhook项目只能自己手动去服务器拉取启动,所以webhook项目使用pm2来管理

补充:

github-action+docker实现自动部署github-webhook+docker实现自动部署原理一样,但是实现步骤有区别:

github-action+docker实现自动部署的详细流程可以看我这篇文章:github-action+docker实现项目自动部署

(1)action是在github中的项目创建workflow工作流(yml脚本文件),yml脚本文件主要执行:

1、对仓库项目进行依赖下载及打包

2、根据项目创建的dockerfile文件生成docker镜像并将镜像push提交到腾讯云镜像仓库中

3、ssh登录腾讯云服务器pull提交的docker镜像并启动

上面的步骤执行完后push提交仓库代码会自动触发yml脚本文件完成自动部署

需要执行的包括创建yml脚本文件、dockerfile文件以及在github配置secret

(2)webhook是在github创建钩子,然后自己配置webhook服务器用于接收提交仓库代码的行为,然后在webhook服务器项目中新建.sh脚本文件用于触发webhook后对应在服务器中执行操作,包括下载项目依赖、打包项目,然后通过项目的dockerfile文件生成docker镜像并启动

webhook执行流程为push仓库代码后触发webhook钩子绑定的webhook服务器地址,执行自己定义的webhook服务器代码,然后根据代码会执行项目对应的sh脚本文件,会在服务器中下载项目依赖、打包项目、根据dockerfile创建docker镜像并启动

总结:action和webhook的原理一样,但是action更简便,不需要自己定义webhook服务器,而且还有一个不同在于action将项目下载依赖、打包项目、生成docker镜像放在了服务器外(github中)执行,而webhook把执行步骤都放在了服务器内执行

一、项目手动部署

在开始介绍自动部署之前,先看一下手动部署怎样实现的,以便于与自动部署进行对比:

1、本地项目上传到github仓库

2、xshell连接服务器,通过yum安装运行项目需要的环境(git、nvm)

# 安装git
yum install git -y

# 安装nvm
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

# 执行nvm命令
source /root/.bashrc

3、生成服务器对于github的ssh公钥并将公钥配置在github中,方便服务器拉取github代码

# 服务器生成ssh
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# 查看生成的ssh公钥
cat /root/.ssh/id_rsa.pub

4、通过nvm安装node(npm),切换npm淘宝镜像源

# nvm安装node的最新稳定版本
nvm install stable

# 切换npm淘宝镜像源,使用cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

5、通过yum安装yum-utils等yum工具、切换yum阿里源

# 安装yum工具
yum install -y yum-utils   device-mapper-persistent-data   lvm2
# 切换yum源
yum-config-manager \
    --add-repo \
    https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

6、服务器新建/usr/projects目录存放项目代码,使用git clone将github的前后端项目代码克隆到该目录

mkdir /usr/projects
# 通过ssh拉取前端项目
git clone [email protected]:zhufengnodejs/vue-front.git
# 通过ssh拉取后端项目
git clone [email protected]:zhufengnodejs/vue-back.git

7、启动项目:切换到后端项目目录->cnpm i 下载依赖->npm run start启动项目(注意服务器开启端口号安全组)、启动前端项目步骤一样

cd /usr/projects/vue-back
# 下载后端项目依赖
cnpm i
# 启动项目
npm run start
# curl命令可以查看url显示的结果
curl http://119.3.102.56:3000/api/users

此时手动部署的项目在服务器断开后就不能访问了,而且本地修改代码后需要手动上传代码然后服务器拉取代码再安装依赖重新启动等,很麻烦

二、项目自动部署

介绍了手动部署项目的方式,再来看看怎样实现自动部署:

1、通过yum安装docker,服务器新建/etc/docker目录修改docker配置文件配置docker阿里云镜像源加速

(docker相当于一个镜像仓库,里面存放着很多镜像比如nginx、centos、包括自己配置的镜像空间存放单独的项目等,配置docker加速可以让docker下载这些镜像的速度加快)

(可以将前端和后端项目分别存放在单独的docker镜像空间中,一个docker镜像空间运行一个项目,下载的项目依赖的版本比如vue、node等互不冲突)

# 安装docker
yum install -y docker-ce docker-ce-cli containerd.io

# 配置docker阿里云镜像源加速
mkdir -p /etc/docker
# 执行命令向文件写入镜像源
tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
}
EOF
# 重载所有修改过的配置文件
systemctl daemon-reload
systemctl restart docker

2、在github项目的settings中的webhooks配置webhook服务器(前端项目和后端项目都需要配置)

(表示该项目提交到github上就会触发配置的webhook,会发请求到webhook配置的服务器上进行逻辑处理比如执行脚本等)

(注意配置的密码在github发请求时会在请求头以签名的形式传递过来,vue-webhook会验证该签名是否正确)

github-webhook+docker实现项目可持续自动化部署,项目部署,github,docker,容器

3、本地新建vue-webhook项目使用node开启该服务器用于接收github发来的请求(webhook.js)、

项目上传到仓库、

服务器clone代码到/usr/projects/vue-webhook、

服务器启动该项目

4、服务器通过npm下载pm2管理vue-webhook项目持续开启

(可以通过pm2 logs查看项目启动日志,通过pm2 flush清空日志)

(使用docker之后就可以不使用pm2管理node项目了,可以通过docker logs -f 容器名查看启动日志,容器启动失败就使用docker logs查看启动日志排错)

cnpm i pm2 -g

配置本地vue-webhook项目package.json文件的启动方式为pm2启动

{
  "scripts": {
    //pm2启动项目,--watch出现错误自动重启项目
    "start": "pm2 start ./webhook.js --watch --name='vue-webhook'",
    //停止项目
    "stop": "pm2 stop vue-webhook"
  },
}

上传更新的vue-webhook代码到仓库

服务器拉取vue-webhook仓库代码

5、配置自动构建后端项目:本地vue-webhook新增后端项目vue-back的自动构建脚本vue-back.sh(名字随便取)

(服务器执行该自动构建脚本可以自动拉取仓库代码并将该项目创建单独的docker空间存放并启动)

# vue-webhook/vue-back.sh

#后端项目自动构建配置
#!/bin/bash
WORK_PATH='/usr/projects/vue-back'
cd $WORK_PATH
# echo命令--语句打印输出在服务器
echo "清理代码"
git reset --hard origin/master
git clean -f
echo "拉取最新代码"
git pull origin master
echo "删除旧容器"
docker stop cha-node-container
docker rm cha-node-container
#删除旧镜像之前必须要先删除依赖镜像的容器
#删除旧镜像是为了旧镜像一直存在占用内存,后续可以思考不删除旧镜像,而是将新镜像修改版本号,旧镜像以老版本号继续存在
echo "删除旧镜像"
docker rmi cha-node:1.0.0
echo "开始构建新镜像"
# 执行到这里会执行后端项目配置的Dockerfile文件中的代码配置创建docker(注意要指定项目的版本号vue-back:1.0.0)
docker build -t vue-back:1.0.0 .
echo "启动新容器"
# 3000:3000代表将服务器主机的3000端口连接到docker内部项目启动的3000端口(访问服务器3000端口就会访问docker内部启动项目的3000端口)
docker container run -p 3000:3000 -d --name vue-back-container vue-back:1.0.0

其中自动创建一个docker镜像存放后端项目需要在后端项目vue-back中新建Dockerfile文件配置该项目的docker镜像空间(包括项目版本、docker内下载项目依赖包、项目启动端口号等)

# vue-back/Dockerfile

#配置后端项目的docker镜像空间(基于node镜像创建docker容器)
FROM node
LABEL name="vue-back"
#目前该项目版本号
LABEL version="1.0.0"
#将服务器下该项目下所有文件拷贝到docker的/app文件夹下
COPY . /app
WORKDIR /app
#docker中配置npm镜像源
RUN npm install -g cnpm --registry=https://registry.npm.taobao.org
#docker中安装项目依赖
RUN cnpm install
#项目端口号(docker对外暴露端口号)
EXPOSE 3000
#在docker中启动项目
CMD npm start

在vue-back后端项目中新建.dockerignore忽略文件,忽略不需要打包到项目的docker镜像空间中的文件

# vue-back/.dockerignore
.git
node_modules
package-lock.json
# 不把docker配置文件打包到docker中,配置文件只在创建docker时有用
Dockerfile
.dockerignore

6、配置自动构建前端项目:和上面构建后端项目步骤一样,但是配置代码不一样在vue-webhook项目新建vue-front.sh脚本,脚本配置不同点在于需要执行npm run build打包项目、

# vue-webhook/vue-front.sh

#前端项目自动构建配置
#!/bin/bash
WORK_PATH='/usr/projects/vue-front'
cd $WORK_PATH
echo "清理代码"
git reset --hard origin/master
git clean -f
echo "拉取最新代码"
git pull origin master
echo "下载项目依赖"
cnpm install
echo "打包最新代码"
npm run build
echo "删除旧容器"
docker stop cha-vue-container
docker rm cha-vue-container
echo "删除旧镜像"
docker rmi cha-vue:1.0.0
echo "开始构建新镜像"
docker build -t vue-front:1.0.0 .
echo "启动新容器"
docker container run -p 80:80 -d --name vue-front-container vue-front:1.0.0

再新建vue-front.conf配置前端项目的nginx(监听端口静态资源请求返回静态资源目录、动态资源请求反向代理到后端)(注意:这里的nginx不是服务器安装的nginx,而是前端项目docker空间中安装的nginx)、

# vue-front/vue-front.conf
# 前端项目的nginx配置
server{
    listen 80;
    server_name 119.3.102.56;
    # 静态资源请求
    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    # 动态资源请求使用反向代理
    location /api {
        proxy_pass http://119.3.102.56:3000;
    }
}

在vue-front项目新建Dockerfile文件配置前端项目的docker镜像(配置自动将打包后的前端项目dist目录放在nginx静态资源目录下,将前端vue-front.conf配置文件放在nginx配置目录下)、

# vue-front/Dockerfile

# nginx服务器
FROM nginx
LABEL name="vue-front"
LABEL version="1.0.0"
# 将打包后的dist文件夹下的文件拷贝到docker中的nginx静态资源文件夹目录html下
COPY ./dist/ /usr/share/nginx/html/
# 将前端nginx配置文件拷贝到docker中的nginx子配置文件夹目录下
COPY ./vue-front.conf /etc/nginx/conf.d/
# 前端项目docker对外暴露端口号设置为80
EXPOSE 80

再新建.dockerignore配置忽略文件

# vue-front/.dockerignore

.git
node_modules
package-lock.json
Dockerfile
.dockerignore

7、在本地vue-webhook项目中的webhook.js文件中处理接收到github传来的触发仓库项目上传操作的请求(即配置了webhook的项目有上传操作)

(处理请求包括验证github请求的请求头中的签名是否正确、验证是否为push操作、如果满足条件开启进程执行sh命令,即sh执行对应有上传仓库操作的项目的脚本(.sh),执行该脚本后会将该项目自动拉取仓库最新代码并刷新该项目的docker并下载依赖后启动该项目)

// vue-webhook/webhook.js

const http = require('http')
let crypto = require('crypto');
//开启进程
var spawn = require('child_process').spawn;
let sendMail = require('./sendMail');
//在github上配置webhooks时输入的secret
const SECRET = '123456';
//配置数据加密方法
function sign(data) {
    return 'sha1=' + crypto.createHmac('sha1', SECRET).update(data).digest('hex')
}const server = http.createServer((req, res) => {
    console.log('------------分割线开始-------------');
    console.log('方法:', req.method, '路径:', req.url);if (req.method === 'POST' && req.url == '/webhook') {
        console.log('请求成功');
        let buffers = [];
        //接收github传递的数据(请求体)
        req.on('data', function (data) {
            console.log('接收github请求体数据');
            buffers.push(data);
        });
        req.on('end', function () {
            console.log('接收github请求体数据完成');
            let body = Buffer.concat(buffers);
            //获取github传递过来的请求头信息
            let sig = req.headers['x-hub-signature'];
            let event = req.headers['x-github-event'];
            let id = req.headers['x-github-delivery'];
            //判断github传递的签名是否符合要求
            if (sig !== sign(body)) {
                console.log('签名验证失败-签名不正确');
                console.log('github签名:', sig, '自己的签名:', sign(body))
                return res.end('Not Allowed');
            }
            console.log('签名验证成功-签名正确');
            res.setHeader('Content-Type', 'application/json');
            res.end(JSON.stringify({ "ok": true }));
            //判断是否是push项目到仓库
            if (event === 'push') {
                console.log('push代码到仓库操作执行');
                let payload = JSON.parse(body);
                //开启进程处理执行对应项目的脚本(第一个参数是命令,第二个参数是文件名)
                console.log(`开始执行脚本文件${payload.repository.name}.sh`);
                let child = spawn('sh', [`./${payload.repository.name}.sh`]);
                let buffers = [];
                //获取执行脚本的进程传递回来的信息(项目构建部署信息)
                child.stdout.on('data', function (buffer) { buffers.push(buffer) });
                child.stdout.on('end', function () {
                    let logs = Buffer.concat(buffers).toString();
                    console.log('获取到执行脚本传递回来的信息');
                    //将部署信息整合发邮件通知
                    sendMail(`
                        <h1>部署日期: ${new Date()}</h1>
                        <h2>部署人: ${payload.pusher.name}</h2>
                        <h2>部署邮箱: ${payload.pusher.email}</h2>
                        <h2>提交信息: ${payload.head_commit && payload.head_commit['message']}</h2>
                        <h2>布署日志: ${logs.replace("\r\n", '<br/>')}</h2>
                    `);
                });
            }
        })} else {
        res.end('Not Found!');
    }
})
​
server.listen(4000, () => {
    console.log('webhook on 4000....');
})

vue-webhook项目中新建sendEmail.js文件配置发邮件的代码,然后配置webhook.js代码在自动化构建成功后调用sendEmail.js的函数发邮件告知部署信息

// vue-webhook/sendEmail.js

const nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
    //host: 'smtp.ethereal.email',
    service: 'qq', // 使用了内置传输发送邮件 查看支持列表:https://nodemailer.com/smtp/well-known/
    port: 465, // SMTP 端口
    secureConnection: true, // 使用了 SSL
    auth: {
        user: '1776875119@qq.com',
        // 这里密码不是qq密码,是你设置的smtp授权码
        pass: 'jjthfwzqjsimejfj',
    }
});
​
​
function sendMail(message) {
    console.log('开始发邮件');
    let mailOptions = {
        from: '"1776875119" <1776875119@qq.com>', // 发送地址
        to: '1776875119@qq.com', // 接收者
        subject: '部署通知', // 主题 
        html: message // 内容主体
    };
    // send mail with defined transport object
    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            return console.log(error);
        }
        console.log('Message sent: %s', info.messageId);
        console.log('------------分割线结束-------------');
    });
}
module.exports = sendMail;

上传vue-webhook项目到仓库、

服务器拉取vue-webhook项目并启动该项目(即启动该项目接收github请求并执行对应项目的脚本实现对应项目的自动构建及部署)

cd /usr/projects/vue-webhook
git pull origin master
cnpm i
# 启动项目(pm2)
npm start
# 查看pm2启动该项目打印的日志
pm2 logs
自动构建部署流程

以前端代码举例,本地修改了前端代码后将代码上传到github仓库,由于该前端项目的仓库配置了webhooks,github监听到上传操作就会发请求到配置webhooks时填写的url(即vue-webhook项目启动的node服务),服务器的vue-webhook接收到github请求就会验证github请求及签名等(验证安全),验证通过就会执行对应前端项目的脚本文件(在服务器执行sh 前端脚本.sh命令),脚本文件会下将仓库代码pull下来,在脚本文件执行到创建docker时就会执行前端项目的Dockerfile文件将项目添加到docker并下载所需环境及依赖后启动前端项目,项目部署成功后会将部署信息以邮件的形式通知我

上面的流程执行完后的效果就是本地修改代码并上传到仓库后,收到邮件通知则代表项目自动构建及部署完成,可以直接访问url查看上传到仓库代码的最新效果

docker概念补充

1、服务器安装docker后,可以创建多个docker容器,每个docker容器相当于一个小的操作系统,每个docker容器中可以安装不同的镜像(nginx、node等),通过这些镜像组成一个项目运行环境,每个docker容器内部自成一个独立的环境,互不影响,比如可以通过nginx镜像为前端项目创建一个docker容器,通过node镜像为后端创建一个docker容器,然后分别在各自的docker容器中启动项目,将启动的docker的端口号对应到服务器主机的端口号,这样外界就可以正常访问了

2、docker这样启动多个容器,不同容器内部有不同的环境,可以解决不同环境(比如node版本不同等)的项目运行在单一环境的服务器出现错误的情况,可以将不同的项目分别创建对应的docker容器,在容器中配置对应的环境,然后在服务器中启动

3、在仓库拉下项目代码后通过Dockerfile文件构建项目的docker容器(在docker内部配置该项目所需环境并启动),就可以不用担心项目运行的环境和本地/服务器的环境不同而报错的问题

4、docker可以通过docker ps查看启动的容器,然后可以通过docker exec -it 容器名 /bin/bash进入容器内部,通过exit退出进入的容器,进入到容器内部会发现容器内部相当于一个小的linux系统,该有的文件夹都有(/etc、/usr等),nginx一样的是下载到etc/nginx里面,nginx静态资源目录也是在/usr/share/nginx/html里面,就是说每一个docker容器内部都是一个完整的linux系统,可以像在linux系统下载或操作文件一样在容器内部进行操作文章来源地址https://www.toymoban.com/news/detail-848449.html

到了这里,关于github-webhook+docker实现项目可持续自动化部署的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .NET Core部署到linux(CentOS)最全解决方案,入魔篇(使用Docker+Jenkins实现持续集成、自动化部署)

    通过前面三篇: .NET Core部署到linux(CentOS)最全解决方案,常规篇 .NET Core部署到linux(CentOS)最全解决方案,进阶篇(Supervisor+Nginx) .NET Core部署到linux(CentOS)最全解决方案,高阶篇(Docker+Nginx 或 Jexus) 通过前面三篇文章的介绍,我们已经对.net core多方案部署到linux下有了非常全面的认识

    2024年02月02日
    浏览(45)
  • 【日常记录】自动化部署与持续交付:GitHub Actions CICD

    当我们做项目的时候,如果做完了,要发布,就需要打包,扔到服务器上,如果改了一点东西,还得打包,扔到服务器上,重复的执行 打包= 扔到服务器上 详细记录如何使用github actions自动化部署项目 自动化部署与持续交付:GitHub Actions CICD 自动化部署一般以下方式 Jenkins

    2024年02月02日
    浏览(65)
  • Jenkins+Docker 实现一键自动化部署项目

    1.安装Jenkins 注:因为Jenkins容器里的用户是Jenkins,而主机用户不是Jenkins,就算是root也一样会报错:/var/jenkins_home/copy_reference_file.log: Permission denied,这个时候就需要在主机上面给主机地址赋予访问Jenkins容器的权限,Jenkins内部用的是uid 1000的user。 -privileged=true让容器具有root权限

    2024年02月16日
    浏览(50)
  • Jenkins+Docker 实现一键自动化部署项目!步骤齐全,少走坑路

    大家好,我是互联网架构师! 本文章实现最简单全面的Jenkins+docker+springboot 一键自动部署项目,步骤齐全,少走坑路。 环境 :centos7+git(gitee) 简述实现步骤:在docker安装jenkins,配置jenkins基本信息,利用Dockerfile和shell脚本实现项目自动拉取打包并运行。 docker 安装社区版本CE

    2024年02月09日
    浏览(48)
  • docker+k8s+jenkins+harbor持续集成自动化部署

    另外一篇文章有讲docker的安装与相关配置,暂时就不讲了 1、关闭防火墙并修改主机名 2、永久禁用swap 用#注释掉swap一行(新版centos已经默认禁用) 3、配置镜像加速 到阿里云获取自己镜像加速地址 4、安装 docker-compose 官网找到下载地址 https://github.com/docker/compose/releases 版本地址

    2024年02月08日
    浏览(63)
  • 详细步骤记录:持续集成Jenkins自动化部署一个Maven项目

    提示:本教程基于CentOS Linux 7系统下进行 1. 下载安装jdk11 官网下载地址:https://www.oracle.com/cn/java/technologies/javase/jdk11-archive-downloads.html 本文档教程选择的是jdk-11.0.20_linux-x64_bin.tar.gz 解压jdk-11.0.20_linux-x64_bin.tar.gz命令为: 2. 下载Jenkins的war包 官网下载地址:https://mirrors.tuna.tsing

    2024年02月04日
    浏览(58)
  • 详解git自动化部署WebHook

    前言:记录自己使用WebHook实现自动化部署项目 个人博客 已更新该文章— 详解git自动化部署WebHook WebHook 功能是帮助用户 push 代码后,自动回调一个设定的 http 地址。 简单来说 就是 监听 执行git操作后向指定 http 地址 发送一个请求。 同时 WebHook 是一个通用的解决方案,可以

    2024年02月15日
    浏览(48)
  • 持续集成交付CICD:基于ArgoCD 的GitOps 自动化完成前端项目应用发布与回滚

    目录 一、实验 1. 环境 2. K8S master节点部署Argo CD 3.基于ArgoCD 实现GitOps (同步部署文件) 4.基于ArgoCD 实现GitOps (同步HELM文件) 二、问题 1. ArgoCD 连接K8S集群状态为 Unknown 2.ArgoCD 创建application失败 3. curl命令 (1)主机 表1 主机 主机 架构 版本 IP 备注 master1 K8S master节点 1.20.6 1

    2024年02月03日
    浏览(50)
  • Apipost自动化测试+Jenkins实现持续集成

    Apipost 自动化测试支持「持续集成」功能,在安装了Apipost的服务器中输入命令,即可运行测试脚本。 创建自动化测试脚本 在创建好的测试用例中选择「持续集成」。 点击新建,配置运行环境、循环次数、间隔停顿后点击保存会生成命令。 安装 Apipost-cli npm install -g apipost-cl

    2024年01月25日
    浏览(66)
  • 自动化金丝雀部署:Flagger全面解读webhook(含源码)

    内容导读: 上文通过下面的配置就实现了 验收测试 和 压力测试 ,对此有以下疑问: metadata定义脚本和类型,说明接口能执行shell,那它是怎么实现的? type未设置是怎样的执行逻辑?type有哪些值,各有什么作用? 本文将通过源码来解答以上问题 本文采用 粗读 源码方式,

    2024年04月11日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包