后端的搭建规划是:启动一个go docker 镜像的container, 用于编译golang项目,并把container的输出(main文件)指向指定目录:/var/lib/jenkins/workspace/my-project-backend 即($PWD)jenkins job的workspace, 然后再把main文件拷贝到一个固定目录下,重命名在执行。
之所以重命名是因为文件名字为main的不容易让人理解这个可执行文件的本意。golang build可以自定义输出结果的名字,但是好像有点复杂??
设计细节解释:
docker一编译出来就放到jenkins job workspace 下目的是:
- 可以从jenkins 页面就可以看出是否有成功编译出main文件,因为jenkins已经设置为在每次build之前都会先清空workspace,所以main肯定是最新的。
- 刚编译出来的main文件不能直接覆盖掉旧有的可执行文件, 因为旧的文件正在被执行。除非在build钱先kill掉后端进程,但是这有可能有因为编译失败导致后端长时间挂机的风险。
执行,直接用nohup 放后端非挂起执行,把执行的log重定向到一个log文件,这个重定向输出是必要的,因为jenkins 里执行nohup 一闪而过,jenkins job process terminal会因此关闭,导致nohup后的程序找不到终端输出而无法成功执行。
搭建步骤:
项目要搭建在我们的build server, 先登录build server,工具用SecureCRT.
以下是我登录的步骤记录,可不看, 你可以直接登录你的目标server就好
a. ssh awsdemo # 这是我自己写的ssh指令, 你可以直接ssh IP
b. build #运行指令跳转到build server, 你可以直接ssh IP
c. sudo su - #由于要安装文件,所以切换到root账号下载golang docker 镜像
a. 确保此时登录的build server上已经安装了go:
比如我在window上的go版本检查
$ go version
go version go1.13.1 windows/amd64
b. pull golang docker镜像:
运行
docker pull golang
docker images | grep go #检查是否已经pull成功
c. 启动docker image 编译main.go ,通过路径挂载,得到build的结果,docker image仅仅做编译用,用后即删。
cd $WORKSPACE #jenkins job的workspace
docker run --rm -v "$PWD":/data/my-project-backend -w /data/my-project-backend golang:1.13.1 go build -v main.go
#把当前目录挂到启动后的docker container的/data/my-project-backend目录下,这个目录会在container启动后自动创建。
#-w为container启动后的工作目录,即让container启动后到这个目录下执行随后指定的命令go build -v main.go
备注:
a.可以下载包含特定golang版本的go docker image , 从tags里输入特定版本号即可找到
b. golang docker image提供了-rm 参数,实现执行完命令后销毁image。
c. docker run 命令详解 docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
d.golang command命令详解
4.执行完后会在WORKSPACE下看到编译出来的main可执行文件,将它拷贝到一个稳定的目录下后,重命名为项目名字,运行
nohup ./my-project-backend >./log 2>&1 &
#nohup, 非挂起执行
# & 置于后台运行
# 2>&1 把错误输出也输出到指定终端。 这里为./log
- 如果需要重新部署,记得先把现有的./my-project-backend 进程kill掉。
oldProcessId=$(ps aux | awk '/[m]agic-lamp-backend/ {print $2}')
if [ ! -z $oldProcessId ]
then
echo "kill old process $oldProcessId"
kill -9 $oldProcessId
fi
有疑问加站长微信联系(非本文作者)