Docker+Jenkins自动化发布前端到远程服务器(一)

421 阅读4分钟

Docker+Jenkins自动化发布前端到远程服务器(一)

​ 之前写了一篇Jenkins自动构建后通知企微的文章,最近抽空把我们目前用的前端自动化构建方案也整理了一下,仅供大家参考学习。

image.png

前言

本篇文章的整体流程较长,主要是针对我们项目的实际情况来制定的,部分步骤在一些简单场景下可以省略(比如选择构建分支),默认你已经对JenkinsDocker有一定的基础和了解,所以只会列举关键步骤的配置;

Jenkins配置

Jenkins所须插件:

管理Jenkins > 系统配置中找到Publish over SSH,配置ssh可以远程连接的服务器信息,多台服务器的话就配置多个SSH Server

image.png

​ 在管理Jenkins > 全局工具配置中找到 NodeJS,选择要安装的Node版本

image.png

  1. 定义构建参数

    我们在这里配置的主要参数如下,可根据实际的项目情况选择

    • 发布环境:开发环境、生成环境或者测试环境(dev/prod/test)
    • 目标服务器的IP:选择要发布到哪个目标服务器
    • 服务器架构(x86/arm64):为了适配arm架构服务器的Docker镜像构建
    • Git代码分支:选择要打包的分支或者tag,可以默认
    • Docker仓库的项目名称:为了构建Docker镜像后同步到仓库,可选 (前提是你的Docker仓库已经建好了项目)
    • Docker镜像的名称:Docker镜像的名称

    我这里主要用到的参数类型就三种:

    • Choice Parameter(选择参数):就是我们的下拉框,可以配置下拉框中的选项值,比如选择构建到哪个目标服务器
    • **Git Parameter(Git参数):**可以选择Git仓库的分支或者Tag进行构建
    • String Parameter(字符串参数): 就是输入框,自定义构建时的字符参数,比如Docker容器的默认启动端口

image.png

参数的定义及到底选用哪个类型完全取决于自己项目的实际情况,如果你觉得构建时输入参数太麻烦,那可以定义为选择参数,或者直接给定默认值;列举几个场景例子:

a. 如果每次构建的分支是固定的,那可以不需要Git Parameter,直接在配置Git仓库的地址时默认分支即可;如果配置了Git Parameter, 那么在构建时,会列举对应仓库的所有分支及Tag,可直接选择

image.png

image.png

b. 如果考虑不同架构服务器,可以不需要下面的选择参数

image.png

c. 如果不考虑Docker容器的默认启动端口,可以不需要下面的配置

image.png

  1. Git仓库配置

    ![image-20240912181407807](C:\Users\WEB\AppData\Roaming\Typora\typora-user-images\image-20240912181407807.png

image.png

如果用了`Git Parameter`,可以选择分支,此处的指定分支可以配置为`Git Parameter`所指定的分支;比如上面图中指定的`Git Parameter`的分支名称变量为`Branch`,那在指定分支引用这个变量即可: `${Branch}`

3. 配置Node版本

image.png

只有通过NodeJs插件安装了指定的NodeJs,这里才能选择。

  1. 执行Shell脚本

image.png

这是我们的一个示例脚本:主要考虑了不同服务器架构、不同部署环境、是否推送镜像到Docker仓库等因素的影响;脚本中所有类似${Framework}都是通过上面提到的参数定义的环境变量;

#!/bin/sh -l
# 镜像tag名称
imageTag=''
# 进入jenkins工作目录
cd ${WORKSPACE}
# 删除历史tar包
rm -f ./${ImageName}-*.tar
# 设置npm淘宝源
npm config set registry https://registry.npmmirror.com
# 依赖安装
npm install --unsafe-perm=true --allow-root
# 编译打包
npm run build:${env}
# Docker镜像打包
if [ ${Framework} = 'arm' ]; then
	docker buildx build --platform=linux/arm64 -f Dockerfile -t ${ImageName}-${Framework} .
    imageTag=${ImageName}-${Framework}
	docker save -o ${ImageName}-${Date}-${Framework}.tar ${ImageName}-${Framework}
	docker rmi -f ${ImageName}-${Framework}
elif [ ${HostName} != 'localhost' ]; then
	# 远程部署
    docker build -f Dockerfile -t ${ImageName}-remote .
    imageTag=${ImageName}-remote
    # 保存镜像为tar包
    docker save -o ${ImageName}-${Date}-${Framework}.tar ${ImageName}-remote
    # 拷贝项目中需要映射的文件
    cp -r ./public/volumes/* ./
    # 保存docker映射文件
    cd ./docker    
    tar -zcvf ../docker.tar ./*
elif [[ "$(docker images -q ${ImageName} 2> /dev/null)" != "" ]]; then
    # 本机部署 如果存在镜像,备份原有镜像
    docker save -o ${ImageName}-old-${Backup}.tar ${ImageName}
    docker rm -f ${ImageName}
    docker rmi -f ${ImageName}
    # 构建最新的Docker镜像
    docker build -f Dockerfile -t ${ImageName} .
    docker run -dp ${Port}:80 --restart=always --privileged=true --name ${ImageName} ${ImageName}
    # 存档最新镜像
    docker save -o ${ImageName}-${Date}.tar ${ImageName}
else
  docker build -f Dockerfile -t ${ImageName} .
  docker run -dp ${Port}:80 --restart=always --privileged=true --name ${ImageName} ${ImageName}
  # 用于存档
  docker save -o ${ImageName}-${Date}.tar ${ImageName}
fi

# 是否推送外网Docker
if [ ${PushOut} = '是' ]; then    
    docker login -u userName -p password ${HarborIntranetAddress}
    docker tag ${imageTag:-$ImageName} ${HarborInternetAddress}/${ProjectName}/${ImageName}
    # docker推送
    docker push ${HarborInternetAddress}/${ProjectName}/${ImageName}
    # 删除本地的tag
    docker rmi ${HarborInternetAddress}/${ProjectName}/${ImageName}
    docker logout
fi

exit 0

以上步骤完成后,最终在构建时会把我们构建的镜像保存为.tar文件,下一步会通过SSH Server.tar文件发送到目标服务器的指定目录,在目标服务器用Docker加载.tar文件,并且自动启动。