内容大概
今天给大伙带来的是通过docker容器将编写好的nodejs进行镜像打包部署,并且在nodejs应用代码更新的时候自动拉取git仓库的nodejs代码进行重新打包部署,从而实现一个CI/CD 、DevOps过程。(docker安装过程省略)
内容目录
- 通过docker拉取一个gogs/gogs镜像,并通过该镜像起一个独立的git仓库容器
- 基于该项目搭建一个简单的nodejs服务(只要可以返回数据给前端就行)
- 基于该nodejs项目里边创建一个dockerfile便于我们将该项目打包成镜像并提交该项目代码到我们的独立仓库(很重要的一点是要把dockerfile文件也上传上去)
- 创建一个基于nodejs开发的deploy项目,目的是跑一个shell脚本拉取我们放在私有git仓库上边的代码到本地进行重新打包发布
- 通过gogs设置事件钩子触发对应的deploy应用路由,实现代码提交自动化拉取打包镜像重新运行容器
内容实现过程
1.拉取gogs/gogs镜像
//通过docker 拉取一个私有仓库镜像docker pull gogs/gogs//在本地创建一个目录gogs/gogs数据存储的目录,并设置一个用户操作权限sudo mkdir /var/gogssudo chown -R ${USER} /var/gogs//创建一个docker网络方便内部容器之间通信//(暂时不考虑不同宿主机之间的docker容器的互相通信)//可通过docker network ls 查看当前docker内部的network bridgedocker network create cicd-net//通过gogs/gogs启动一个docker container容器,并将该docker连接到刚刚建立的cicd-net上边//启动gogs容器,并将宿主机的端口8888映射到docker内部的3000端口,将9999->22 并//通过-v(全称volumn)挂载本地/var/gogs/ 作为/data的一个映射,进行本地化存储sudo docker run -d --name=gogs --network cicd_net -p 8888:3000 -p 9999:22 -v /var/gogs/:/data gogs/gogs
以上创建好了gogs仓库的服务之后我们就可以本地访问(或远程宿主机的服务ip)8888端口并创建一个账号,用于本地项目的创建啦~,效果如下图
2.在gogs仓库上边创建一个项目并设置我们的ssh-key 方便我们拉取到本地
在本地生成一个对应的密钥,通过以下指令的方式:
cd .ssh
ssh-keygen -t rsa -C "xxx.mail.com"
然后将密钥复制到账户设置下的ssh密钥
这样子之后我们就可以愉快的拉取一个项目,在本地进行开发
3.搭建简单一个nodejs服务并将它打包成一个docker image镜像
//将刚刚创建好的一个私有git 仓库下的代码拉取下来,并在里边创建一个index.js文件//代码如下const http=require('http');http.createServer((req,res)=>{ res.end('i am a web this is a auto merge hooks')}).listen(3000,()=>{ console.log("webserver start")})//使用yarn or npm 初始化一个package.json文件yarn init or npm run init//创建一个Dockerfile文件//并进行如下编写#基于node:12.13-alpine的layer进行编写FROM node:12.13-alpine#在本地创建一个/usr/src/app文件夹并定位到该文件夹WORKDIR /usr/src/app#将package*.json相关文件复制到该文件夹下COPY package*.json ./#安装 在dependence下边的生成环境的包RUN npm install --only=production//将所有内容都复制到该目录下COPY . .//通过node运行该应用CMD ["node","index.js"]
以上就完成了我们一个简单的应用,接下来我们在当前项目的目录下执行docker build -t 镜像名 . 生成一个镜像,运行docker run -d -p 3000:3000 --name=cicdweb cicd-web,测试一下我们这个镜像是否和我们预期得到的结果一样,如下图
这个时候将我们写好的所有代码都提交到私有仓库上边
4.重新创建一个基于nodejs开发的deploy项目,目的是跑一个shell脚本拉取我们放在私有仓库上边的代码并将其重新打包成一个新的镜像
//在该项目下新建一个index.js文件const http=require('http');const cp=require('child_process');http.createServer((req,res)=>{// 通过一个子进程的方式运行deploy.sh 脚本 let proc=cp.exec('./deploy.sh',()=>{}) //将子进程的信息打印到主进程中 proc.stdout.pipe(process.stdout); proc.stderr.pipe(process.stderr); res.end('i can deploy server');}).listen(4000,()=>{ console.log("deploy start")})//创建一个deploy.sh脚本文件#! /bin/sh#定义一个变量并将我们远程项目名赋值给它pjName='cicd_web'//判断当前www文件夹下是否存在该项目if [ ! -d "www/${pjName}" ];then echo 'git clone' #新建一个www文件夹 mkdir www cd www #clone该项目到当前的docker容器里边(暂时不考虑不同宿主机的拉取方式), #gogs为刚才创建的gogs容器名字,以及仓库访问的一个端口, #刚刚的8888是宿主机映射的端口,我们容器间需要访问对应容器的端口 git clone http://gogs:3000/chopper/${pjName} cd ${pjName}else echo 'git pull' #存在该项目,直接拉取下来 cd www/${pjName} git pullfi#通过宿主机的docker将cicdweb容器暂停并删除,并删除原先的镜像docker stop cicdwebdocker rm -f cicdwebdocker rmi -f cicd-web#在当前的容器内部通过dockerfile重新创建一个镜像docker build -t cicd-web .#重新开启镜像docker run --name=cicdweb -d -p 3000:3000 cicd-web//接下来创建一个本项目的dockerfileFROM node:12.13-alpine#需要下载git,用于拉取代码RUN apk add gitWORKDIR /usr/src/appCOPY package*.json ./RUN npm install --only=productionCOPY . .CMD ["node","index.js"]
然后通过docker build -t cicd-deploy . 的方式创建一个deploy镜像,再运行它:
//通过/var/run/docker.sock,/usr/local/bin/docker 将宿主机的docker提供给容器内部使用// 并设置访问权限--user rootdocker run -d -p 4000:4000 --name=deploy --network cicd_net -v /usr/local/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock --user root cicd-deploy
通过以上代码我们可以实现一个deploy镜像并启动一个容器,这个时候当我们访问localhost:4000的时候就可以查看到该容器内部会进行远程代码的拉取并打包出一个新的cicd-web容器,如下图
这个时候我们就实现了手动触发它,远程应用代码并重新打包代码为镜像以容器的方式运行的目的
5.实现代码提交自动化拉取打包镜像重新运行容器
接下来在我们的gogs仓库上边设置触发应用自动拉取的钩子
设置推送的地址,并选择触发的事件进行推送触发重新拉取更新应用
6.查看拉取记录
通过以上的搭建之后,我们就能够在我们提交代码时候进行自动化重新部署应用的目的啦,有问题欢迎各位后台留言哦~