【ci】ci过程中的一些坑点

801 阅读2分钟

背景

我们项目组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里操作就行,

image.png

然后在执行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('启动成功')      //日志打印