优雅的通过Shell脚本生成Go的程序包
前言
随着Go语言的普及,越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署(CI/CD)工具,用于自动化构建、测试和部署Go程序包,但存在一些部署在ECS服务器的Go程序包或需要手动编译打包上传镜像仓库的镜像。然而,手动创建和管理这些程序包可能会变得相当繁琐。因此,为了提高开发效率,使用Shell脚本来自动化这个过程是一个不错的选择。
Shell脚本
针对上述说到的两种情况:一个是部署在ECS上Go服务程序包、另一个是手动部署K8s上的Go服务镜像包,下面分别给出代码。
一键生成Go程序包
本人使用Window系统开发,使用Go的gracehttp实现服务平滑重启,但Window对信号量处理存在问题,导致在Window环境下生成的Go程序包无法平滑重启,所以这里使用alpine将项目编译生成程序包到本地项目目录中,完美解决该问题。
deploy.sh
#!/bin/bash# 定义环境变量
environments=("test" "prod")
image="go-demo"# 函数:显示绿色成功信息
function success {echo -e "\033[1;32m$1\033[0m"
}# 函数:显示绿色成功信息
function info {echo -e "\033[33m$1\033[0m"
}# 函数:显示红色错误信息并退出
function error {echo -e "\033[1;31m$1\033[0m"exit 1
}info "Please select the packaging environment:(Select number) "
select env in "${environments[@]}"; doif [ "$env" == "test" ]; thenport="80"success "The packaging environment you entered is: $env"breakelif [ "$env" == "prod" ]; thenport="8080"success "The packaging environment you entered is: $env"breakelseerror "Invalid environment selection, please re-enter"exit 1fi
doneinfo "\nbuild start:"info "\n1) docker build running..."
docker build --build-arg PORT="$port" -t "$image:$env" -f deploy/docker/Dockerfile . &> /dev/nullinfo "\n2) docker running..."
docker run -itd --name "$image-$env" "$image:$env" &> /dev/nullinfo "\n3) docker cp package..."
docker cp "$image-$env:/app/main_$port" ./info "\n4) delete containers..."
docker ps -a | grep "$image-$env"* | awk '{print $1}' | xargs docker rm -f &> /dev/nullinfo "\n5) remove images..."
docker rmi -f $(docker images "$image:$env"* -q | sort | uniq) &> /dev/nullinfo "\nbuild done!"exit 0
Dockerfile
FROM golang:1.17.6-alpineLABEL maintainer="xxx@xxx.com"# 文件名称
ARG PORT# 设置工作目录
ENV WORKDIR /app# 关闭CGO
ENV CGO_ENABLED 0# 设置GOOS和GOARCH
ENV GOOS linux
ENV GOARCH amd64
ENV GOPROXY https://goproxy.cn,direct# 声明工作目录
WORKDIR $WORKDIR# 拷贝整个项目到工作目录
COPY . .# 项目依赖包
RUN go mod download# 项目编译
RUN go build -ldflags="-s -w" -o $WORKDIR/main_$PORT ./main.go# 运行300s
# CMD ["sleep", "300"]
执行结果

一键生成Go镜像包
现在我们很多项目部署在K8s上,所以将程序编译打包成进行镜像,其中需要将代码打包成程序包,而且需要将程序包上传到仓库,供k8s下载使用,通过编写Xshell程序,可以大大提高效率。
deploy.sh
#!/bin/bash# 仓库域名
WAREHOUSE_DOMAIN="harbor.xxx.com"
# 镜像路径
MIRROR_PATHNAME="xxx/login"# 函数:显示绿色成功信息
function success {echo -e "\033[1;32m$1\033[0m"
}# 函数:显示绿色成功信息
function info {echo -e "\033[33m$1\033[0m"
}read -p "Please enter the packaging version:" version
success "The packaging version you entered is: $version\n"info "build start:\n"info "1) docker build...\n"
docker build -f ./deploy/docker/Dockerfile -t "$MIRROR_PATHNAME:$version" . &> /dev/nullinfo "2) docker tag...\n"
docker tag "$MIRROR_PATHNAME:$version" "$WAREHOUSE_DOMAIN/$MIRROR_PATHNAME:$version" &> /dev/nullinfo "3) docker push...\n"
docker push "$WAREHOUSE_DOMAIN/$MIRROR_PATHNAME:$version" &> /dev/nullinfo "4) delete containers...\n"
docker ps -a | grep "$WAREHOUSE_DOMAIN/$MIRROR_PATHNAME*" | awk '{print $1}' | xargs docker rm -f &> /dev/nullinfo "5) remove images...\n"
docker rmi -f $(docker images "$WAREHOUSE_DOMAIN/$MIRROR_PATHNAME*" -q | sort | uniq) &> /dev/nullinfo "build done!"exit
Dockfile
# =========================================== 第一阶段:构建应用程序 ===========================================
FROM golang:1.17.6-alpine AS builder # 设置维护者信息
LABEL maintainer="xxx@xxx.com" # 设置工作目录
ENV WORKDIR /app # 关闭CGO,以减少构建过程中的依赖和体积
ENV CGO_ENABLED 0 # 设置目标操作系统和架构
ENV GOOS linux
ENV GOARCH amd64
ENV GOPROXY https://goproxy.cn,direct # 切换到工作目录
WORKDIR $WORKDIR # 拷贝当前目录下的所有文件到工作目录
COPY . . # 下载项目依赖包
RUN go mod download # 查看工作目录中的文件列表,可以用来检查文件是否正确拷贝
RUN ls -al # 编译项目,-ldflags参数用于优化生成的二进制文件大小和性能
RUN go build -ldflags="-s -w" -o $WORKDIR/main ./main.go # =========================================== 第二阶段:构建Docker镜像 ===========================================
FROM loads/alpine:3.8# 设置维护者信息
LABEL maintainer="xxx@xxx.com" # 设置工作目录和时区
ENV WORKDIR /app
ENV TZ Asia/Shanghai # 将第一阶段构建的应用程序复制到当前镜像的工作目录
COPY --from=builder /app/main $WORKDIR/main
RUN chmod +x $WORKDIR/main# 切换到工作目录
WORKDIR $WORKDIR # 设置容器启动时的命令为应用程序的可执行文件路径
CMD ["./main"]
执行结果

结语
通过编写Shell脚本,我们可以大大简化Golang项目的打包和部署流程,提升工作效率。当然,实际生产环境中可能还需要考虑更多因素,如版本管理、依赖处理、日志收集等,但以上步骤已经构成了一个基础的自动化部署框架。随着需求的增加,你可以在这个基础上不断扩展和完善你的部署脚本,使其更加符合你的业务需求。
相关文章:
优雅的通过Shell脚本生成Go的程序包
前言 随着Go语言的普及,越来越多的开发人员选择使用Go编写代码。虽然越来越多的公司项目已使用持续集成/持续部署(CI/CD)工具,用于自动化构建、测试和部署Go程序包,但存在一些部署在ECS服务器的Go程序包或需要手动编译…...
益生菌抗癌?补充这种益生菌,抑制肝癌,还改善肠道健康
撰文 | 宋文法 肠道菌群,是人体不可分割的组成部分,生活在我们肠道内的数万亿细菌对健康起着重要作用,它们影响着人的新陈代谢、消化能力、抵御感染、控制人体对药物的反应,甚至还能预防某些癌症。 非酒精性脂肪肝病,是…...
LLM漫谈(二)| QAnything支持任意格式文件或数据库的本地知识库问答系统
一、QAnything介绍 QAnything (Question and Answer based on Anything) 是致力于支持任意格式文件或数据库的本地知识库问答系统,可断网安装使用。 您的任何格式的本地文件都可以往里扔,即可获得准确、快速、靠谱的问答体验。 目前已支持格式: PDF&…...
Linux环境vscode clang-format格式化:vscode clang format command is not available亲测有效!
问题现象 vscode安装了clang-format插件,但是使用就报错 问题原因 设置中配置的clang-format插件工具路径不正确。 解决方案-亲测有效! 确认本地安装了clang-format工具:终端输入clang-format(也可能是clang-format-13等版本…...
Vue3前端 响应式数据 知识点
一、ref(基本类型数据,也可以定义对象类型的响应式数据。此时底层用的还是reactive) ref 创建基本类型的响应式数据 作用:定义响应式变量语法: let xxx ref(初始值)返回值: 一个 RefImp1 的实例对象,简称 ref对象或ref,ref 对象的 value 属…...
golang数据库连接池设置多少比较合适,如何设置?
设置数据库连接池的大小需要综合考虑应用程序的需求、数据库系统的性能、服务器资源等因素。连接池大小的不合理设置可能导致性能问题或资源浪费。 以下是一些建议: 考虑应用程序的并发需求: 连接池的大小应该足够满足应用程序的并发需求。如果你的应用…...
一、Mybatis 简介
本章概要 简介持久层框架对比快速入门(基于Mybatis3方式) 1.1 简介 https://mybatis.org/mybatis-3/zh/index.html MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁移到了Google Code。随着开发团队转投G…...
苹果Vision Pro将于1月27日上市!
在无数期待中,苹果全新产品Vision Pro头显终于定下上市日期。 彭博社记者马克古曼(Mark Gurman)于近日在X(前推特)平台爆料了这一信息,预计苹果Vision Pro头显将于2024年1月27日率先在美国上市。 在过去看…...
密码学(一)
文章目录 前言一、Cryptographic Primitives二、Cryptographic Keys2.1 Symmetric key cryptography2.2 asymmetric key cryptography 三、Confidentiality3.1 Symmetric key encryption algorithms3.2 asymmetric key block ciphers3.3 其他 四、Integrity4.1 secure hashing …...
VueRouter
1、用户权限问题 可以在路由全局前置守卫判断当前vuex里是否有token 有token值证明刚才登录过, 无token值证明未登录 router.beforeEach((to, from, next) > {const token store.state.tokenif (token) {// 如果有token, 证明已登录if (!store.state.userInfo.username) {/…...
什么是React.FC | 封装ant design弹框组件之:ant design 修改密码弹框组件
文章目录 一、什么是React.FC组件的 props 是什么意思二、封装ant design弹框组件之:ant design 修改密码弹框组件定义修改密码弹框组件使用修改密码弹框组件:[重要]关于提交时候,不同组件 表单数据共享报错:Button cannot be used as a JSX component.一、什么是React.FC …...
DHCP
一、DHCP 1.1 什么是dhcp DHCP动态主机配置协议,通常被应用在大型的局域网络环境中,主要作用是集中地管理、分配IP地址,使网络环境中的主机动态的获得IP地址、DNS服务器地址等信息,并能够提升地址的使用率。 DHCP作为用应用层协…...
VS code的使用介绍
VS code的使用介绍 简介下载和安装常用的插件使用教程快捷键 集成Git未找到 Git。请安装 Git,或在 "git.path" 设置中配置。操作步骤打开文件夹初始化仓库文件版本控制状态提交文件到git打开git操作栏位 好用的插件ChineseDraw.io Integration实体关系 Gi…...
【蓝桥杯选拔赛真题57】python兔子分胡萝卜 第十四届青少年组蓝桥杯python 选拔赛比赛真题解析
目录 python兔子分胡萝卜 一、题目要求 1、编程实现 2、输入输出...
Spring MVC中JSON数据处理方式!!!
添加json依赖 <!--spring-json依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.0</version></dependency> 注解 RequestBody:作…...
学习JavaEE的日子 阶段回顾
标识符 含义:给类、变量、方法、接口取名字的时候使用到的字符序列 组成:大小写字母 、数字、$、_、中文 注意事项: 不能以数字开头 区分大小写字母 不能使用除了$和_以外的特殊符号 不能使用Java的关键字 考虑到编码问题不要使用中文 关…...
深入理解 Flink(一)Flink 架构设计原理
大数据分布式计算引擎设计实现剖析 MapReduce MapReduce 执行引擎解析 MapReduce 的组件设计实现图 Spark 执行引擎解析 Spark 相比于 RM 的真正优势的地方在哪里:(Simple、Fast、Scalable、Unified) DAG 引擎中间计算结果可以进行内存持…...
Python pip 常用指令
前言 Python的pip是一个强大的包管理工具,它可以帮助我们安装、升级和管理Python的第三方库。以下是一些常用的pip指令。 1. 安装第三方库 使用pip安装Python库非常简单,只需要使用pip install命令,后面跟上库的名字即可。 # 安装virtuale…...
Eureka工作原理详解
摘要:本文将详细介绍Eureka的工作原理,包括服务注册、服务发现、心跳检测等关键概念。通过阅读本文,您将了解到Eureka如何实现高可用、可扩展的服务注册中心。 一、引言 在微服务架构中,服务注册与发现是一个重要的环节。为了实…...
开源加解密库之GmSSL
一、简介 GmSSL是由北京大学自主开发的国产商用密码开源库,实现了对国密算法、标准和安全通信协议的全面功能覆盖,支持包括移动端在内的主流操作系统和处理器,支持密码钥匙、密码卡等典型国产密码硬件,提供功能丰富的命令行工具及…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...
