背景
我们项目组ci/cd没有一起,因为部署是在k8s里的,所以cd过程是登录master节点手动修改yml文件,然后apply重启服务就可以了。所以要做的只有ci。
常规理解
ci服务器上启一个node镜像,把代码git pull下来,然后npm i,然后npm run build,然后再把dist代码放到打包容器外,然后在外面根据dockerfile再打包成部署镜像。
坑1,镜像可以分开
我之前理解的是希望在一个镜像里完成build和deploy,所以想着有一个有node和nginx镜像的集成镜像,但是发现无论是在node里装nginx还是nginx里装node,都不是一件容易的事情。
可以打包的时候管打包,部署的时候管部署。
分两个镜像。
坑2.node镜像中没有安装node-sass
在 node:lastest 中,没法安装node-sass,安装不成功。
后来改到node:14.10.0中勉强装上。
node-sass一直是一个天坑,但是框架代码里又会有。
另外,npm的常规操作:
安装npm
npm config set sass_binary_site=npm.taobao.org/mirrors/nod…
坑3,node镜像中npm i太慢
这个可能是网络原因,换源也没法解决。后来想的方案是把node_modules打包在镜像里。
每次只把最近代码copy进文件夹,不重新npm i
坑4,隐藏文件没有copy
无论是 cp 还是 docker cp 都一样的。
-R 是把目录都复制,但是隐藏文件不会复制,如.env.production这个配置文件。
进而导致build报错。
解决方法,用参数 -a
或者几个隐藏文件一个一个来。
5. ci的参数化
主要是 镜像的标签。
这个在jenkins里操作就行,
然后在执行shell中使用 ${image_tag}
坑6. shell的参数化
接收参数执行npm run build:env
用的时候,直接 sh xxx.sh master就行了。
但是在shell中定义变量切记不要用空格。
my_env="prod"
my_env = "prod"
这样子不一样。。
正文
第一步,构建build镜像
vts.registry/build/node:14.10.0-1
node: 14.10.0 + 指定目录/home/vts-web2,指定目录/hoome/code下有完整的node_modules, 即不用再npm i了。
第二步,在jenkins上npm run build
docker run -v /home/jenkins/workspace/vts-web2:/home/vts-web2 -w /home vts.registry/build/node:14.10.0-1 /bin/sh -c "sh /home/vts-web2/build.sh stage"
/home/jenkins/workspace/vts-web2是ci服务器上的工作目录,代码git拉取在这里。
和build容器内路径互相挂载。然后执行 build.sh脚本。
#!/bin/sh
# npm install --registry=https://registry.npm.taobao.org
my_env="prod"
if [ $1 ]
then
my_env=$1
echo "env is" $1
fi
cp -R -a /home/vts-web2/* /home/code
cd /home/code
npm run build:$my_env
mkdir /home/vts-web2/dist
cp -R /home/code/dist/* /home/vts-web2/dist
主要完成的是,cp最新拉下来的代码到/home/code下,覆盖。
然后执行npm run build:env
执行之后再把dist文件,cp回/home/vts-web2下,即ci服务器工作目录目录下。
第三部,docker build
打镜像
docker build -t vts.registry/vts/vts-web-test:${image_tag} .
Dockerfile放在根目录下。
FROM nginx:latest
WORKDIR /
COPY default.conf /etc/nginx/conf.d/
COPY deploy.sh /home/ws/
COPY dist/ /home/ws/vts-web/
RUN chmod 777 /home/ws/deploy.sh
拉取nginx镜像,把conf、dist、deploy copy进去就行。
第四部,docker push
docker push vts.registry/vts/vts-web-test:${image_tag}
第五步,cd/测试
docker run -tid -p 8888:5000 vts.registry/vts/vts-web-test:${image_tag} sh /home/ws/deploy.sh
deploy的脚本内容是:
#!/bin/bash
/usr/sbin/nginx -g "daemon off;"
这样子nginx服务就可以跑起来,外部根据port访问。
题外话
本来打算用node启服务的,不用nginx。用node pm2启动。
不过最后还是选了nginx。
有bff后再弄node写个koa吧。
如果用node,
DockerFILE
WORKDIR /
COPY deploy.sh /home/ws/
COPY vts-web/ /home/ws/vts-web/
RUN chmod 777 /home/ws/deploy.sh
depoly.sh
#!/bin/bash cd /home/ws/vts-web node server.js
server.js
const Koa = require('koa') //koa2中间件依赖
const app = new Koa() //js的继承
const static = require('koa-static') //静态资源服务插件
// 配置静态资源
app.use(static('./'));
app.use(async (ctx) => {
console.log(ctx, '123')
ctx.body = 'vts-web'
})
app.listen(5000) //服务启动端口
console.log('启动成功') //日志打印