docker部署jenkins并且实现go程序和前端程序自动化部署,看这一篇就够了。
这篇博文记录了我从零到一部署jenkins时踩的坑,并一步一步解决的过程。
jenkins部署失败方案
容器部署
拉取最新jenkins镜像,并部署容器
docker run --name jenkins -u root -d -p 8086:8080 -p 50000:50000 \
-e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai" \
--restart=always \
-v /xxx/jenkins/jenkins_home:/var/jenkins_home \
-v /xxx/jenkins/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
jenkinsci/blueocean
初始化
浏览器访问: ip+端口
发现安装插件报错
进一步排查,发现版本过低,不支持安装这些插件。
然后升级版本。
升级完版本后发现,最新版本java8 不能运行。于是开始升级java环境。
使用dockerfile部署,指定镜像java版本
# 使用官方 Jenkins 镜像作为基础镜像
FROM jenkins/jenkins:latest
# 设置环境变量,指定时区
ENV TZ=Asia/Shanghai
# 使用 apt-get 更新包列表并安装 Java 17
USER root
RUN apt-get update && \
apt-get install -y openjdk-17-jdk && \
rm -rf /var/lib/apt/lists/*
# 设置 JAVA_HOME 环境变量
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
# 更改权限,确保 Jenkins 用户可以执行 docker 命令
RUN chmod +x /usr/bin/docker
# 将 jenkins 用户添加到 docker 组,以便在容器内运行 docker 命令
RUN usermod -aG docker jenkins
# 清理工作
USER jenkins
进入该dockerfile文件目录下运行下面命令构建镜像
docker build -t my-jenkins .
注意,java11下载依赖下载得需要些时间
待镜像构建成功后,从此镜像启动容器
docker run --name jenkins -u root -d -p 8086:8080 -p 50000:50000 \
-e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai'" \
--restart=always \
-v /xxx/jenkins_new/jenkins_home:/var/jenkins_home \
-v /xxx/jenkins_new/docker.sock:/var/run/docker.sock \
-v /xxx/jenkins_new/bin/docker:/usr/bin/docker \
my-jenkins
网络问题,失败构建。寻求其他方案
jenkins部署成功方案
最后发现,只有jenkins最新版本安装插件时才不会有大量报错
备注
我使用的是docker-compose部署的go程序,所以需要在宿主机上安装docker-compose,docker,go环境。相关环境安装移步后面标题。
- 拉取镜像
docker pull jenkins/jenkins:2.456
- 运行容器
docker run --name jenkins -u root -d -p 8086:8080 -p 50000:50000 -e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai" --restart=always -v /xxx/jenkins_new/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/go:/usr/local/go -v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose jenkins/jenkins:2.456
- 查看初始密码
cat /xxx/jenkins_new/jenkins_home/secrets/initialAdminPassword
- 安装推荐插件
初始化
汉化
初始化管理员账号密码邮箱等信息
进来后你会发现不是完全汉化版本,删除默认汉化插件,重新安装并重启容器。
进入插件管理搜索 “locale”
重启容器后
其他必要插件
安装 Publish over SSH、docker-build-step 、Docker Commons 插件
配置服务器信息
测试连通性
构建项目
宿主机安装go环境并代理到jenkins容器
运行发现报错找不到go命令,原因是jenkins容器中并没有go环境,因此需要安装go环境。两种方式:1.容器内安装go环境;2.宿主机安装go环境,挂载到容器
下面我们使用方式二:
宿主机中操作:
# 下载Go语言1.22.5二进制包
wget https://go.dev/dl/go1.22.5.linux-amd64.tar.gz
# 解压缩到/usr/local目录(这个目录是Go官方推荐的安装目录)
sudo tar -C /usr/local -xzf go1.22.5.linux-amd64.tar.gz
# 设置用户环境变量
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile
echo 'export GOPATH=$HOME/go' >> ~/.profile
source ~/.profile
# 设置系统环境变量
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
echo 'export GOPATH=$HOME/go' >> /etc/profile
source /etc/profile
# 检查是否安装成功
go version
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
//删除容器,并挂载配置文件路径后重新启动
docker stop jenkins
docker rm jenkins
//重新启动
docker run --name jenkins -u root -d -p 8086:8080 -p 50000:50000 -e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai" --restart=always -v /xxx/jenkins_new/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/go:/usr/local/go -v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose jenkins/jenkins:2.456
安装docker-compose
为什么不效仿go环境一样:宿主机安装环境,挂载到jenkins容器呢?
应为docker-compose启动是通过python,如果宿主机安装代理后,还需要为jenkins容器安装python环境
直接在jenkins容器中直接安装docker-compose
- 开始
docker exec -it jenkins bash
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
- 输出信息:
root@9f4de87d743f:/# curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 12.1M 0 70992 0 0 34265 0 0:06:11 0:00:02 0:06:09 62603
3 12.1M 3 458k 0 0 2142 0 1:39:06 0:03:39 1:35:27 4134
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
root@9f4de87d743f:/# chmod +x /usr/local/bin/docker-compose
root@9f4de87d743f:/# docker-compose --version
[183] Cannot open self /usr/local/bin/docker-compose or archive /usr/local/bin/docker-compose.pkg
- 分析:
在 Jenkins 容器中通过 curl 下载 docker-compose 文件时出现了问题,导致文件不完整(Cannot open self 错误通常是因为文件损坏或下载未完成)。
在宿主机中下载docker-compose挂载到jenkins容器中
1.下载
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o docker-compose
chmod +x docker-compose
- 确认文件大小和权限是否正确:
ls -lh docker-compose
- 挂载到容器中:
docker run --name jenkins -u root -d -p 8086:8080 -p 50000:50000 -e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai" --restart=always -v /xxx/jenkins_new/jenkins_home:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker -v /usr/local/go:/usr/local/go -v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose jenkins/jenkins:2.456
- 在容器中确认是否正确安装:
docker exec -it jenkins bash
docker-compose --version
编写构建shell脚本
#!/bin/bash
##### 环境变量 #####
env="test"
project_name="zhijian"
name="zhi-client"
time=$(date "+%Y%m%d%H%M%S")
image="${project_name}/${name}:${time}"
##### 打印脚本执行开始时间 #####
echo "脚本开始执行,时间:$(date "+%Y-%m-%d %H:%M:%S")"
echo "当前工作目录:$(pwd)"
##### 设置 Go 环境 #####
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPROXY=https://goproxy.cn
##### 检查 Go 是否安装 #####
if ! command -v go &>/dev/null; then
echo "错误: Go 未安装,请先安装 Go 环境!"
exit 1
fi
##### 清理 Go 模块缓存并下载依赖 #####
echo "正在清理 Go 模块缓存并下载依赖..."
go mod tidy
if [ $? -ne 0 ]; then
echo "错误: Go 模块下载失败,请检查依赖!"
exit 1
fi
echo "进入$env环境"
cd env/$env
echo "当前工作目录:$(pwd)"
ls
##### 编译 Go 程序 #####
echo "正在删除旧的 main 文件..."
rm -rf ./main
if [ $? -ne 0 ]; then
echo "警告: 删除旧的 main 文件失败,可能不存在。"
fi
ls
echo "正在编译 Go 程序..."
go build ../../main.go
if [ $? -ne 0 ]; then
echo "错误: Go 程序编译失败,请检查代码!"
exit 1
fi
echo "Go 程序编译完成!"
ls
##### 构建 Docker 镜像 #####
echo "正在构建 Docker 镜像,名称为:$image"
docker build -t $image .
if [ $? -ne 0 ]; then
echo "错误: Docker 镜像构建失败,请检查 Dockerfile!"
exit 1
fi
##### 检查 docker-compose 是否安装 #####
if ! command -v docker-compose &>/dev/null; then
echo "错误: docker-compose 未安装,请先安装 docker-compose!"
exit 1
fi
##### 停止并移除所有容器 #####
echo "正在停止所有容器..."
docker-compose down
if [ $? -ne 0 ]; then
echo "错误: 容器停止失败,请检查 docker-compose 配置!"
exit 1
fi
##### 构建并启动容器 #####
echo "正在构建并启动容器..."
DOCKER_IMAGE=$image docker-compose up -d
if [ $? -ne 0 ]; then
echo "错误: 容器启动失败,请检查 docker-compose 配置!"
exit 1
fi
# 获取镜像的完整标识(按时间排序,保留最新的 3 个,删除其余的)
echo "清理旧镜像,保留最新 3 个..."
docker images --filter=reference="*/$name:*" --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" \
| sort -rk 2 | tail -n +4 | awk '{print $1}' | xargs -r docker rmi -f
echo "旧镜像清理完成!"
##### 打印容器状态 #####
echo "正在获取容器状态..."
docker-compose ps
##### 打印脚本执行结束时间 #####
echo "脚本执行完成,时间:$(date "+%Y-%m-%d %H:%M:%S")"
清理镜像逻辑
docker images --filter=reference="*/$name:*" --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" \
| sort -rk 2 | tail -n +4 | awk '{print $1}' | xargs -r docker rmi -f
- 筛选特定镜像:
docker images --filter=reference="*/$name:*" --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}"
- filter=reference="/$name:":筛选所有与 zhi-client 名称匹配的镜像。
- format "{}:{} {}":输出格式为 REPOSITORY:TAG CreatedAt。
- 按时间排序:
- 按 CreatedAt 降序排列,最新的镜像排在最前。
- 跳过最新的 3 个:
tail -n +4
- 跳过前三行(保留最近三个镜像)。
- 提取镜像名称:
awk '{print $1}'
- 提取 REPOSITORY:TAG,作为删除镜像的输入。
- 删除多余镜像:
xargs -r docker rmi -f
- 批量删除镜像,-r 确保在没有多余镜像时不执行删除命令。
这里由于是docker-compose 部署的,所以出现共用同一网桥问题。换docker直接部署
#!/bin/bash
##### 环境变量 #####
env="test"
project_name="xxx"
name="xxx"
time=$(date "+%Y%m%d%H%M%S")
image="${project_name}/${name}:${time}"
container_name="xxx"
##### 打印脚本执行开始时间 #####
echo "脚本开始执行,时间:$(date "+%Y-%m-%d %H:%M:%S")"
echo "当前工作目录:$(pwd)"
##### 设置 Go 环境 #####
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPROXY=https://goproxy.cn
##### 检查 Go 是否安装 #####
if ! command -v go &>/dev/null; then
echo "错误: Go 未安装,请先安装 Go 环境!"
exit 1
fi
##### 清理 Go 模块缓存并下载依赖 #####
echo "正在清理 Go 模块缓存并下载依赖..."
go mod tidy
if [ $? -ne 0 ]; then
echo "错误: Go 模块下载失败,请检查依赖!"
exit 1
fi
##### 进入指定环境目录 #####
echo "进入 $env 环境"
cd "env/$env" || { echo "错误: 无法进入目录 env/$env"; exit 1; }
echo "当前工作目录:$(pwd)"
ls
##### 编译 Go 程序 #####
echo "正在删除旧的 main 文件..."
rm -rf ./main
if [ $? -ne 0 ]; then
echo "警告: 删除旧的 main 文件失败,可能不存在。"
fi
echo "正在编译 Go 程序..."
go build ../../main.go
if [ $? -ne 0 ]; then
echo "错误: Go 程序编译失败,请检查代码!"
exit 1
fi
echo "Go 程序编译完成!"
##### 构建 Docker 镜像 #####
echo "正在构建 Docker 镜像,名称为:$image"
docker build -t "$image" .
if [ $? -ne 0 ]; then
echo "错误: Docker 镜像构建失败,请检查 Dockerfile!"
exit 1
fi
##### 停止并删除现有容器 #####
echo "正在停止现有容器:$container_name"
if docker ps -q --filter "name=^/${container_name}$" | grep -q .; then
docker stop "$container_name"
fi
echo "正在删除现有容器:$container_name"
if docker ps -a -q --filter "name=^/${container_name}$" | grep -q .; then
docker rm "$container_name"
fi
##### 启动新容器 #####
echo "正在启动新容器:$container_name"
docker run -d \
--name "$container_name" \
--restart always \
-p 7788:7788 \
-e TZ="Asia/Shanghai" \
-v /usr/share:/usr/share \
-v /xxx/xxx/xxx-mini/log:/xxx/xxx/log \
-v /xxx/xxx/xxx-mini/cert:/xxx/xxx/cert \
"$image"
if [ $? -ne 0 ]; then
echo "错误: 容器启动失败,请检查日志!"
exit 1
fi
##### 删除多余的旧镜像标签 #####
echo "清理旧镜像标签,保留最近 3 个..."
# 获取目标镜像的所有标签,按创建时间排序,排除最近 3 个
docker images --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" | \
grep "$name" | \
sort -k2,2 -r | \
tail -n +4 | \
awk '{print $1}' | \
xargs -r docker rmi -f
if [ $? -eq 0 ]; then
echo "旧镜像标签清理完成!"
else
echo "警告: 旧镜像清理过程中出现问题,请手动检查。"
fi
##### 打印容器状态 #####
echo "正在获取容器状态..."
docker ps -a | grep $container_name
##### 打印脚本执行结束时间 #####
echo "脚本执行完成,时间:$(date "+%Y-%m-%d %H:%M:%S")"
最后
讨论
- 过程中是不是会觉得不断删除容器,在创建容器,那我之前的配置和初始化岂不是没了?
非也,我们已经将容器数据挂载到了宿主机中,所以即使删除了容器,再次因为挂载地址问题重新创建容器,我们的数据并不会丢失。 - 这个过程是否太过麻烦?
是的,使用docker部署jenkins确实麻烦。不仅需要考虑到环境的挂载,还需要寻找docker中jenkins最新版本。可以直接在官网下载jenkins的linux包,安装到宿主机上,这样就不用考虑环境挂载问题了。
参数解释:
docker run:
用来创建并启动一个容器。
--name jenkins:
给容器指定一个名称,容器的名字是 jenkins,以后可以通过这个名称来引用容器。
-u root:
以 root 用户身份运行容器。这通常是为了确保容器内有足够的权限来执行某些操作,如安装软件或执行 Docker 命令。
-d:
让容器以后台模式运行。即容器在启动后会在后台运行,不会阻塞终端。
-p 8086:8080:
将宿主机的 8086 端口映射到容器的 8080 端口。Jenkins 的 Web UI 默认是通过 8080 端口访问的,容器内的 8080 端口会映射到宿主机的 8086 端口,允许从宿主机访问 Jenkins。
-p 50000:50000:
将宿主机的 50000 端口映射到容器的 50000 端口。这个端口用于 Jenkins 的代理连接。代理通常使用该端口来连接主 Jenkins 实例。
-e JAVA_OPTS="-Dorg.apache.commons.jelly.tags.fmt.timeZone='Asia/Shanghai'":
设置一个环境变量 JAVA_OPTS,并配置时区为 Asia/Shanghai,即设置容器内的时区为上海时间。
--restart=always:
设置容器自动重启策略。如果容器停止或崩溃,Docker 会自动重新启动容器。always 表示无论容器停止的原因如何,都将自动重启。
-v /xxx/jenkins_new/jenkins_home:/var/jenkins_home:
将宿主机路径 /xxx/jenkins_new/jenkins_home 挂载到容器内的 /var/jenkins_home 目录。这是 Jenkins 容器的默认工作目录,保存所有 Jenkins 的配置、插件和构建数据。挂载宿主机目录可以持久化 Jenkins 的数据。
-v /var/run/docker.sock:/var/run/docker.sock:
将宿主机的 Docker socket 文件 /var/run/docker.sock 挂载到容器内。这是为了让容器内的 Jenkins 能够与宿主机的 Docker 引擎进行通信,执行 Docker 命令(比如创建、启动容器)。
-v /usr/bin/docker:/usr/bin/docker:
将宿主机的 Docker 可执行文件 /usr/bin/docker 挂载到容器内,使得容器内可以执行 Docker 命令。
-v /usr/local/go:/usr/local/go:
将宿主机的 Go 语言安装目录 /usr/local/go 挂载到容器内的同一目录。这通常用于构建 Go 语言项目的环境。
-v /usr/local/bin/docker-compose:/usr/local/bin/docker-compose:
将宿主机的 docker-compose 可执行文件 /usr/local/bin/docker-compose 挂载到容器内。这使得容器内的 Jenkins 可以使用宿主机的 docker-compose 工具。
jenkins/jenkins:2.456:
这是指定要使用的 Docker 镜像,jenkins/jenkins 是官方的 Jenkins 镜像,版本号为 2.456。这个镜像包含了 Jenkins 的所有依赖和配置,能够在容器中运行 Jenkins。
前端部署
使用nvm安装node和npm
cd ~
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
# 手动加载 nvm 的配置
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # 这会加载 nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # 这会加载 bash_completion
nvm --version
nvm install 18
nvm use 18
node -v
npm -v
# 为了确保每次打开终端时都能自动加载 nvm 配置,可以将以下内容添加到 ~/.bashrc 文件中
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
source ~/.bashrc
本地安装
wget https://nodejs.org/dist/v22.11.0/node-v22.11.0-linux-x64.tar.xz
mkdir /usr/local/lib/node
tar xf node-v22.11.0-linux-x64.tar.xz
mv node-v14.17.4-linux-x64 /usr/local/lib/node/nodejs
sudo vim /etc/profile
# 末尾加
export NODEJS_HOME=/usr/local/lib/node/nodejs
export PATH=$NODEJS_HOME/bin:$PATH
# 重新生效
source /etc/profile
node -v
npm -v
#配置淘宝镜像
# 显示当前源
npm config get registry
npm config set registry https://registry.npm.taobao.org
npm config get registry
# npm install -g cnpm --registry=https://registry.npm.taobao.org
npm --no-optional install -g cnpm --registry=https://registry.npm.taobao.org
【完结】
jenkins本地部署
为什么要本地部署呢,本地部署不需要配置docker中的环境,大大缩短了配置时间
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war/2.456/jenkins.war
java -jar jenkins.war --httpPort=8886
# 浏览器访问 ip+8886
# 查看密码
cat /root/.jenkins/secrets/initialAdminPassword
后台启动,并输出日志
nohup java -jar jenkins.war --httpPort=8080 > jenkins.log 2>&1 &
前端部署脚本
#!/bin/bash
export PATH=$PATH:/usr/local/lib/node/nodejs/bin
echo "检查node环境..."
node -v
npm -v
##### 环境变量 #####
env="dev"
project_name="dist"
time=$(date "+%Y%m%d%H%M%S")
build_dir="dist"
deploy_dir="/xxx/xxx/xxx/html/${project_name}" # Nginx 的静态文件目录
##### 打印脚本开始时间 #####
echo "脚本开始执行,时间:$(date "+%Y-%m-%d %H:%M:%S")"
echo "当前工作目录:$(pwd)"
##### 拉取最新代码 #####
echo "拉取最新代码..."
git pull origin $env
if [ $? -ne 0 ]; then
echo "错误: 拉取代码失败,请检查 Git 仓库配置!"
exit 1
fi
echo "当前工作目录:$(pwd)"
##### 安装依赖 #####
echo "安装依赖..."
cnpm i
if [ $? -ne 0 ]; then
echo "错误: 依赖安装失败,请检查 package.json!"
exit 1
fi
##### 构建项目 #####
echo "构建项目..."
cnpm run build
if [ $? -ne 0 ]; then
echo "错误: 构建失败,请检查代码!"
exit 1
fi
##### 部署静态文件 #####
echo "部署静态文件..."
rm -rf ${deploy_dir}
mkdir -p ${deploy_dir}
cp -r ${build_dir}/* ${deploy_dir}/
if [ $? -ne 0 ]; then
echo "错误: 部署静态文件失败,请检查目录权限!"
exit 1
fi
##### 打印部署结果 #####
echo "部署完成!静态文件已复制到:${deploy_dir}"
ls -lh ${deploy_dir}
##### 打印脚本结束时间 #####
echo "脚本执行完成,时间:$(date "+%Y-%m-%d %H:%M:%S")"
跨服务器部署
构建步骤1. 打包文件
##### 环境变量 #####
env="pro"
project_name="xxx_p"
name="xxx_p_name"
time=$(date "+%Y%m%d%H%M%S")
image="${project_name}/${name}:${time}"
container_name="xxx_p_name"
##### 打印脚本执行开始时间 #####
echo "脚本开始执行,时间:$(date "+%Y-%m-%d %H:%M:%S")"
echo "当前工作目录:$(pwd)"
##### 设置 Go 环境 #####
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPROXY=https://goproxy.cn
##### 检查 Go 是否安装 #####
if ! command -v go &>/dev/null; then
echo "错误: Go 未安装,请先安装 Go 环境!"
exit 1
fi
##### 清理 Go 模块缓存并下载依赖 #####
echo "正在清理 Go 模块缓存并下载依赖..."
go mod tidy
if [ $? -ne 0 ]; then
echo "错误: Go 模块下载失败,请检查依赖!"
exit 1
fi
echo "进入$env环境"
cd env/$env
echo "当前工作目录:$(pwd)"
ls
##### 编译 Go 程序 #####
echo "正在删除旧的 main 文件..."
rm -rf ./main
if [ $? -ne 0 ]; then
echo "警告: 删除旧的 main 文件失败,可能不存在。"
fi
ls
echo "当前工作目录:$(pwd)"
echo "正在编译 Go 程序..."
export GOPATH=/root/go
export GOROOT=/usr/local/go
export GOOS=linux
export GOARCH=amd64
export CGO_ENABLED=0
go build ../../main.go
if [ $? -ne 0 ]; then
echo "错误: Go 程序编译失败,请检查代码!"
exit 1
fi
echo "Go 程序编译完成!"
ls
步骤二,上传到其他服务器
ls
pwd
cd /xxx_p_name/xxx_p/xxx_p-web
ls
env="pro"
project_name="xxx_p"
name="zhi-client"
time=$(date "+%Y%m%d%H%M%S")
image="${project_name}/${name}:${time}"
container_name="zhi-client"
echo "当前工作目录:$(pwd)"
echo "当前目录下文件:$(ls)"
##### 构建 Docker 镜像 #####
echo "正在构建 Docker 镜像,名称为:$image"
docker build -t $image .
if [ $? -ne 0 ]; then
echo "错误: Docker 镜像构建失败,请检查 Dockerfile!"
exit 1
fi
##### 停止并删除现有容器 #####
echo "正在停止现有容器:$container_name"
if docker ps -q --filter "name=^/${container_name}$" | grep -q .; then
docker stop "$container_name"
fi
echo "正在删除现有容器:$container_name"
if docker ps -a -q --filter "name=^/${container_name}$" | grep -q .; then
docker rm "$container_name"
fi
##### 启动新容器 #####
echo "正在启动新容器:$container_name"
docker run -d \
--name "$container_name" \
--restart always \
-p 8084:8084 \
-e TZ="Asia/Shanghai" \
-v /usr/share:/usr/share \
-v /xxx_p_name/xxx_p/xxx_p-web/cert:/xxx_p_name/xxx_p/cert \
"$image"
if [ $? -ne 0 ]; then
echo "错误: 容器启动失败,请检查日志!"
exit 1
fi
# 获取镜像的完整标识(按时间排序,保留最新的 3 个,删除其余的)
echo "清理旧镜像,保留最新 3 个..."
docker images --filter=reference="*/$name:*" --format "{{.Repository}}:{{.Tag}} {{.CreatedAt}}" \
| sort -rk 2 | tail -n +4 | awk '{print $1}' | xargs -r docker rmi -f
echo "旧镜像清理完成!"
##### 打印容器状态 #####
echo "正在获取容器状态..."
docker ps -a | grep $container_name
##### 打印脚本执行结束时间 #####
echo "脚本执行完成,时间:$(date "+%Y-%m-%d %H:%M:%S")"
Jpom一键自动化部署
更轻量级的部署方案
jpom地址
goploy一键自动化部署
参考文档:
评论区