
golang+docker部署
【代码】golang+docker部署。
·
推荐使用第二种方式!!!
推荐使用第二种方式!!!
推荐使用第二种方式!!!
1. 第一种方式本机编译golang可执行文件
1. 本机编译golang可执行文件
2. 构建docker镜像,删除容器,启动最新版本容器
3. sh脚本如下(启动报错可能是数据库、redis等地址用的127.0.0.1,可以配置host
#!/bin/sh name=$1 version=$2 logs="/apps/$name/logs" conf="/apps/$name/config" if [ ! -d $logs ];then mkdir -p $logs fi if [ ! -d $conf ];then mkdir -p $conf fi go build main.go docker build -f Dockerfile3 -t $name:$version . rm -f main docker rm $name -f # --add-host=myhost:192.168.1.100 docker run --name $name -p 8080:8080 -v $logs:/apps/logs -v $conf:/apps/config -d $name:$version
config目录下的配置文件记得copy一份到挂载目录
cp ./config/* /apps/xxxx/config
dockerfile如下
# 表示依赖 alpine 最新版 FROM alpine:latest # 下载Alpine镜像很慢有时候会卡住,因为使用的资源默认是境外服务器,将境外服务器替换为国内服务器即可 RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories LABEL MAINTAINER="Joker" LABEL EMAIL="xxx@qq.com" ENV VERSION 1.0 # 在容器根目录 创建一个 apps 目录 WORKDIR /apps # 挂载容器目录 VOLUME ["/apps/config"] VOLUME ["/apps/logs"] # 可执行文件拷贝当前目录下 ADD main /apps/main # 拷贝配置文件到容器中 COPY config /apps/config # COPY logs /apps/logs # 设置时区为上海 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo 'Asia/Shanghai' >/etc/timezone # 设置时区(以 Asia/Shanghai 为例) RUN apk add --no-cache tzdata ENV TZ=Asia/Shanghai # 设置编码 ENV LANG C.UTF-8 # 暴露端口 EXPOSE 8080 # 运行golang程序的命令 CMD ["./main"]
2. 第二种方式,使用容器编译
此方式的好处是本机不需要golang环境,而且打包出来的容器大小和第一种方式一样
sh脚本如下
#!/bin/sh set -x name=$1 version=$2 mode=$3 logs="/tmp/apps/$name/logs" conf="/tmp/apps/$name/config" if [ ! -d $logs ];then sudo mkdir -p $logs fi if [ ! -d $conf ];then sudo mkdir -p $conf fi if [ -z "$name" ] || [ -z "$version" ] || [ -z "$mode" ]; then echo "请依次输入 项目名称 版本号 部署环境" exit 1 fi # git操作 sudo chmod 777 -R .git/ git pull # go build main.go sudo docker build -f Dockerfile3 -t $name:$version . # 判断是否存在名为 "xxx" 的容器 if sudo docker ps -a --format '{{.Names}}' | grep -q "$name"; then # 停止并删除容器 sudo docker stop "$name" sudo docker rm "$name" -f echo "${name}容器已停止" fi # 获取当前版本镜像的 ID current_image_id=$(sudo docker images -q $name:$version) # 之前版本镜像都删掉 sudo docker images | awk -v name="$name" -v version="$version" -v current_image_id="$current_image_id" '$1 == name && $2 != version && $3 != current_image_id { print $3 }' | xargs -I {} sudo docker rmi {} # # 之前版本镜像也都删掉 # if sudo docker images -q $name; then # sudo docker rmi $(docker images -q $name) # echo "${name}镜像已删除" # fi # conf暂时不挂载 sudo docker run --name $name -p 8080:8080 -v $logs:/apps/logs -e Mode="$mode" -d $name:$version # docker run --name $name -p 8080:8080 -v $logs:/apps/logs -v $conf:/apps/config -d $name:$version # docker run --name $name -p 8080:8080 \ # --mount type=bind,source=$logs,target=/apps/logs \ # --mount type=bind,source=$conf,target=/apps/config \ # -d $name:$version
dockerfile如下
FROM golang:1.20.5-alpine as builder # 这里在docker里也使用go module的代理服务 ENV GOPROXY https://goproxy.cn,direct ENV GO111MODULE on # 在容器根目录 创建一个 apps 目录 RUN mkdir -p /apps # 设置工作目录 WORKDIR /apps COPY . /apps ## 编译 RUN go build -o /apps/main ./main.go # ============================================================ # ============================================================ # ======================= 运行应用 ============================ # ============================================================ # ============================================================ # 表示依赖 alpine 最新版 FROM alpine:latest # 下载Alpine镜像很慢有时候会卡住,因为使用的资源默认是境外服务器,将境外服务器替换为国内服务器即可 RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories LABEL MAINTAINER="Joker" LABEL EMAIL="xxxx@qq.com" ENV VERSION 1.0 # 在容器根目录 创建一个 apps 目录 RUN mkdir -p /apps # 设置工作目录 WORKDIR /apps # 挂载容器目录 VOLUME ["/apps/config"] VOLUME ["/apps/logs"] # 可执行文件拷贝当前目录下 COPY --from=builder /apps/main /apps/main # 拷贝配置文件到容器中 COPY --from=builder /apps/config /apps/config # COPY --from=builder logs /apps/logs # 设置时区为上海 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo 'Asia/Shanghai' >/etc/timezone # 设置时区(以 Asia/Shanghai 为例) RUN apk add --no-cache tzdata ENV TZ=Asia/Shanghai # 设置编码 ENV LANG C.UTF-8 # 暴露端口 EXPOSE 8080 # 运行golang程序的命令 CMD ["./main"]
sh脚本太多了怎么办,那就放到一个shell里面
#!/bin/bash
# cd ../entry_manage
function show_help {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " --mode=<mode> Set the mode (local, dev, test, prod)"
echo " --v=<version> Set the version number"
echo " --name=<name> Set the project name"
echo " --help Show this help message"
}
# 保存输入的参数
args=("$@")
# 使用 shift 命令去除已处理的位置参数
shift
# 处理命令行参数
for ((i = 0; i < "${#args[@]}"; i++)); do
case "${args[$i]}" in
--mode=*|-mode=*)
mode="${args[$i]#*=}"
;;
--mode|-mode)
mode="${args[$((i+1))]}"
;;
--v=*|-v=*)
version="${args[$i]#*=}"
;;
--v|-v)
version="${args[$((i+1))]}"
;;
--name=*|-name=*)
name="${args[$i]#*=}"
;;
--name|-name)
name="${args[$((i+1))]}"
;;
--help)
show_help
exit 0
;;
esac
done
if [ -z "$name" ]; then
echo "请输入项目名称"
exit 1
fi
# 检查 mode 是否合法
valid_modes=("" "local" "dev" "test" "prod")
valid=false
for valid_mode in "${valid_modes[@]}"; do
if [ "$mode" = "$valid_mode" ]; then
valid=true
break
fi
done
# 如果 mode 不在合法的模式值中,则输出错误信息
if ! $valid; then
echo "mode值只能是:空值 local, dev, test, prod."
exit 1
fi
logs="/apps/$name/log"
conf="/apps/$name/config"
if [ ! -d $logs ]; then
sudo mkdir -p $logs
fi
if [ ! -d $conf ]; then
sudo mkdir -p $conf
fi
# git操作
echo "更新代码..."
# sudo chmod 777 -R .git/
# git pull
function setVersoin {
# 获取上一个镜像版本
previous_version=$(sudo docker images | awk '$1 == "'${name}'" && $2 != "latest" {print $2}' | sort -rV | head -n 1)
if [ -z "$previous_version" ]; then
# 如果没有上一个版本,则默认设置为 1.0.0
version="1.0.0"
else
# 去除可能存在的 "v" 字符串
version_without_v=$(echo "$previous_version" | sed 's/^v//')
# 将上一个版本的主版本号、次版本号和修订号分离出来
major=$(echo "$version_without_v" | awk -F'.' '{print $1}')
minor=$(echo "$version_without_v" | awk -F'.' '{print $2}')
patch=$(echo "$version_without_v" | awk -F'.' '{print $3}')
# 递增修订号,如果修订号超过 10,则递增次版本号
patch=$((patch + 1))
if [ "$patch" -ge 10 ]; then
patch=0
minor=$((minor + 1))
fi
# 如果次版本号超过 10,则递增主版本号
if [ "$minor" -ge 10 ]; then
minor=0
major=$((major + 1))
fi
# 更新新版本号
version="$major.$minor.$patch"
fi
}
if [ -z "$version" ]; then
setVersoin
fi
echo "项目:${name} 版本:${version} 环境:${mode}"
function deploy1 {
sudo docker build -f Dockerfile -t $name:$version .
sudo docker rm $name -f
sudo docker run --restart=always --name $name -p 8087:8080 -v $logs:/apps/log -e Mode="$mode" -d $name:$version
}
function deploy2 {
sudo rm -f main
go build -o main main.go
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main main.go
sudo chown root:root main
sudo chmod +x main
sudo docker build -f Dockerfile2 -t $name:$version .
sudo rm -f main
sudo docker rm $name -f
sudo docker run --restart=always --name $name -p 8087:8080 -v $logs:/apps/log -e Mode="$mode" -d $name:$version
}
function deploy3 {
sudo docker build -f Dockerfile3 -t $name:$version .
# 判断是否存在名为 "xxx" 的容器
if sudo docker ps -a --format '{{.Names}}' | grep -q "$name"; then
# 停止并删除容器
sudo docker stop "$name"
sudo docker rm "$name" -f
echo "${name}容器已停止"
fi
# 获取当前版本镜像的 ID
current_image_id=$(sudo docker images -q $name:$version)
# 之前版本镜像都删掉
# sudo docker images | awk -v name="$name" -v version="$version" -v current_image_id="$current_image_id" '$1 == name && $2 != version && $3 != current_image_id { print $3 }' | xargs -I {} sudo docker rmi {}
# conf暂时不挂载
sudo docker run --restart=always --name $name -p 8087:8080 -v $logs:/apps/log -e Mode="$mode" -d $name:$version
}
echo "请选择dockerfile:"
echo "1. Dockerfile"
echo "2. Dockerfile2"
echo "3. Dockerfile3"
# 使用 read 命令读取用户输入,并将输入的值赋给变量 choice
read -p "请输入选项的序号: " choice
# 根据用户输入的值进行不同的处理
case $choice in
1) deploy1 ;;
2) deploy2 ;;
3) deploy3 ;;
*) echo "无效的选项。" ;;
esac
使用sh脚本
# 自动递增版本
./deploy.sh --name xxx -mode=local
# 指定镜像版本打包
./deploy.sh --name xxx -v=1.0
# 自动递增版本、不指定环境变量
./deploy.sh --name xxx
# 指定版本、指定环境
./deploy.sh --name xxx -v=1.0 -mode=local
更多推荐
所有评论(0)