当前位置: 首页 > news >正文

优雅的通过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&#xff1a;作…...

学习JavaEE的日子 阶段回顾

标识符 含义&#xff1a;给类、变量、方法、接口取名字的时候使用到的字符序列 组成&#xff1a;大小写字母 、数字、$、_、中文 注意事项&#xff1a; 不能以数字开头 区分大小写字母 不能使用除了$和_以外的特殊符号 不能使用Java的关键字 考虑到编码问题不要使用中文 关…...

深入理解 Flink(一)Flink 架构设计原理

大数据分布式计算引擎设计实现剖析 MapReduce MapReduce 执行引擎解析 MapReduce 的组件设计实现图 Spark 执行引擎解析 Spark 相比于 RM 的真正优势的地方在哪里&#xff1a;&#xff08;Simple、Fast、Scalable、Unified&#xff09; DAG 引擎中间计算结果可以进行内存持…...

Python pip 常用指令

前言 Python的pip是一个强大的包管理工具&#xff0c;它可以帮助我们安装、升级和管理Python的第三方库。以下是一些常用的pip指令。 1. 安装第三方库 使用pip安装Python库非常简单&#xff0c;只需要使用pip install命令&#xff0c;后面跟上库的名字即可。 # 安装virtuale…...

Eureka工作原理详解

摘要&#xff1a;本文将详细介绍Eureka的工作原理&#xff0c;包括服务注册、服务发现、心跳检测等关键概念。通过阅读本文&#xff0c;您将了解到Eureka如何实现高可用、可扩展的服务注册中心。 一、引言 在微服务架构中&#xff0c;服务注册与发现是一个重要的环节。为了实…...

开源加解密库之GmSSL

一、简介 GmSSL是由北京大学自主开发的国产商用密码开源库&#xff0c;实现了对国密算法、标准和安全通信协议的全面功能覆盖&#xff0c;支持包括移动端在内的主流操作系统和处理器&#xff0c;支持密码钥匙、密码卡等典型国产密码硬件&#xff0c;提供功能丰富的命令行工具及…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...