微服务 云原生:基于 Gogs + Drone 实现 CI/CD 自动化
一般构建部署
以一个简单的前后端项目来说,分别编写前后端的 Dockerfile 文件并构建镜像,然后编写 docker-compose.yml 构建部署,启动运行。每次代码变更后都需重新手动打包、构建、推送。
一个简单的例子:
- 前端:
- 项目名:kubemanagement-web
- 技术栈:Vue
- 后端:
- 项目名:kubemanagement
- 技术栈:Golang
tips: 不同语言对应的构建逻辑编写不同。关于 Dockerfile 以及 docker-compose 如何编写,请查阅官方文档,此处不在赘述。
1. 编写前端 Dockerfile 文件:
#第一阶段构建
FROM node:16.13.2 as builder
WORKDIR /app/kubemanagement-webCOPY . .RUN npm config set registry https://registry.npmmirror.com
RUN npm install# 开始构建
RUN npm run build:prod# 第二阶段构建
FROM nginx
COPY --from=builder /app/kubemanagement-web/dist/ /usr/share/nginx/html/
COPY --from=builder /app/kubemanagement-web/default.conf.template /etc/nginx/templates/default.conf.template
EXPOSE 80
2. 编写后端 Dockerfile 文件:
FROM golang:1.20-alpine3.16 as builder
WORKDIR /go/src/kubemanagement.com/server
COPY . .RUN go env -w GO111MODULE=on \&& go env -w GOPROXY=https://goproxy.cn,direct \&& go env -w CGO_ENABLED=0 \&& go env \&& go mod tidy \&& go build -o server .FROM alpine:latestLABEL MAINTAINER="zj20162325@163.com"WORKDIR /go/src/kubemanagement.com/server
COPY --from=0 /go/src/kubemanagement.com/server/config.yaml ./config.yaml
COPY --from=0 /go/src/kubemanagement.com/server/.kube/config ./.kube/config
COPY --from=0 /go/src/kubemanagement.com/server/server ./
EXPOSE 8082
ENTRYPOINT ./server
3. 分别构建镜像:
- 前端
docker build -t harbor.kubemanagement.com/kubemanagement/kubemanagement-web:v1.0 .
- 后端
docker build -t harbor.kubemanagement.com/kubemanagement/kubemanagement:v1.0 .
结果如下:

如果需要推送镜像,比如推送到私有 Harbor 仓库,可执行:
docker push harbor.kubemanagement.com/kubemanagement/kubemanagement-web:v1.0
docker push harbor.kubemanagement.com/kubemanagement/kubemanagement:v1.0
Harbor 的搭建可参考 微服务 & 云原生:搭建 Harbor 私有镜像仓库。
4. 编写 docker-compose.yml 文件:
version: "3"networks:network:ipam:driver: defaultconfig:- subnet: '177.7.0.0/16'services:web:container_name: kubemanagement-webimage: harbor.kubemanagement.com/kubemanagement/kubemanagement-web:v1.0restart: alwaysenvironment:BACKEND_HOST: 'http://177.7.0.12:8082/'ports:- '8081:80'depends_on:- servernetworks:network:ipv4_address: 177.7.0.11server:container_name: kubemanagement-serverimage: harbor.kubemanagement.com/kubemanagement/kubemanagement:v1.0restart: alwaysports:- '8082:8082'networks:network:ipv4_address: 177.7.0.12
使用 docker-compose 自动完成包括构建镜像,创建服务,启动服务,并关联服务相关容器的一系列操作:
docker-compose up -d
结果如下:

此时通过相应 ip:port 即可访问页面,示例页面如下:

使用 Gogs & Drone 持续集成

Gogs
编写 gogs 的 docker-compose.yml 文件
version: "3"volumes:gogsdata:services:gogs:container_name: gogsimage: gogs/gogs:0.12.10volumes:- gogsdata:/datarestart: alwaysports:- '10880:3000'
执行:
docker-compose up -d
结果如下:

通过 10880 端口访问:

数据库根据需求来选,这里选择最轻量级的 SQLite3 作为演示,其他配置项可以默认,由于编写 docker-compose.yml 时做了端口映射,主要修改域名、端口号,如下:

编写完可选配置后点击立即安装,我这里就简单设置管理员信息:

gogs 的使用与 git 基本一致,简单创建一个仓库并提交信息:

Drone
编写 docker-compsoe.yml 文件:
version: "3"volumes:dronedata:services:drone-server:image: drone/drone:2container_name: drone-serverenvironment:DRONE_AGENTS_ENABLED: "true"DRONE_GOGS_SERVER: "http://192.168.65.134:10880"# openssl rand -hex 16 生成, server 与 runner 的 DRONE_RPC_SECRET 设置相同DRONE_RPC_SECRET: "02cfbfe91f999c6f334158f4cf737490"DRONE_SERVER_HOST: "192.168.65.134:9080"DRONE_SERVER_PROTO: "http"# 必须是管理员身份,方便后续的配置选项等操作DRONE_USER_CREATE: "username:BetaCatPro,admin:true"volumes:- dronedata:/datarestart: alwaysports:- '9080:80'- '9443:443'drone-runner:image: drone/drone-runner-docker:1container_name: drone-runnerenvironment:DRONE_RPC_SECRET: "02cfbfe91f999c6f334158f4cf737490"DRONE_RPC_HOST: "192.168.65.134:9080"DRONE_RPC_PROTO: "http"DRONE_RUNNER_CAPACITY: "2"DRONE_RUNNER_NAME: "first-runner"volumes:- /etc/docker/:/etc/docker- /var/run/docker.sock:/var/run/docker.sockrestart: alwaysports:- '3000:3000'depends_on:- drone-server
部分参数说明:
- DRONE_GOGS_SERVER : Gogs 服务地址(需要http://开头)
- DRONE_RPC_SECRET: Drone 服务密匙(runner 也要使用相同密钥)
- DRONE_SERVER_HOST: Drone 服务地址,外部可访问的域名或IP地址
- DRONE_SERVER_PROTO: Drone提供服务的协议类型,可选为 http 或 https
- DRONE_USER_CREATE: 设置Drone管理员账号(是Gogs平台里的账号)
执行 :
docker-compose up -d
结果:

浏览器访问 ip:port:

登录用户名密码为上一步注册 gogs 时所用的,登录成功进入主页:

这里会显示 gogs 中创建的代码仓库列表。
流水线配置
激活钩子
进入 drone 相应仓库页面,点击 ACTIVATE REPOSITORY 按钮,激活钩子:

激活后可以看到一些设置项,注意一定要把 Trusted 选型勾选,否则在后续编写钩子文件定义挂载操作时会出现下面错误:
Drone untrusted repositories cannot mount host volumes

进入到 gogs 中相应仓库,点击仓库设置:

可以看到管理的 Web 钩子:

编写 .drone.yml 钩子文件
在项目根目录下编写 .drone.yml 文件,用于定义触发 git 提交时的一系列操作,这里以文章开头描述的 kubemanagement-web 前端项目为例:
kind: pipeline
type: docker
name: kubemanagement-web-publishenvironment:GOOS: linuxGOARCH: amd64steps:- name: buildimage: plugins/dockervolumes:- name: hostspath: /etc/hosts- name: docker-capath: /etc/docker- name: dockersockpath: /var/run/docker.socksettings:username: adminpassword:# 注意在 drone 页面的 Secrets 添加对应配置from_secret: harbor_passwordrepo: harbor.kubemanagement.com/kubemanagement/kubemanagement-webregistry: harbor.kubemanagement.comtags:- v1.1- name: ssh commandsimage: appleboy/drone-sshsettings:host: 192.168.65.134username: rootpassword:# 注意在 drone 页面的 Secrets 添加对应配置from_secret: ssh_passwordport: 22script:#拉取镜像并重启 注意--需要提前在目标主机完成docker login- if [ $(docker ps -a | grep kubemanagement-web | wc -l) -ge 1 ];then docker stop kubemanagement-web && docker rm kubemanagement-web; fi- docker pull harbor.kubemanagement.com/kubemanagement/kubemanagement-web:v1.1- export BACKEND_HOST=http://192.168.65.134:8082/- docker run --name kubemanagement-web --restart=always -d -p8081:80 -e BACKEND_HOST=$BACKEND_HOST harbor.kubemanagement.com/kubemanagement/kubemanagement-web:v1.1
volumes:- name: hostshost:path: /etc/hosts- name: docker-cahost:path: /etc/docker- name: dockersockhost:path: /var/run/docker.sock
然后在 drone 页面的 Secrets 添加对应配置,这里按照 .drone.yml 文件中使用到的有 harbor_password 和 ssh_password,value 分别为对应平台的密码,我这里 harbor 的密码为123456,gogs 密码为 by6671715,分别添加即可:

编写好文件后,可进行代码提交。不过还需要查看 gogs 的配置文件中有没有将 ip 加入到白名单中,如果有多个 ip 则用 , 分隔。我这里 ip 为 192.168.65.134。具体配置如下:
- 首先查看 gogs 挂载的卷,查看 Mounts 里 Source 的内容(注意,时下图箭头指向的位置),配置文件即在此目录下:
docker inspect gogs

cd /var/lib/docker/volumes/gogs_gogsdata/_data
cd gogs/conf
vim app.ini
- 在 security 处加上配置:
LOCAL_NETWORK_ALLOWLIST = 192.168.65.134

3. 重启 gogs
# 返回存放 gogs 的 docker-compose.yml 的目录
docker-compose restart
如果没有配置,还继续提交代码的话,会出现下面情况:


可以看到,虽然提交成功,但点击仓库设置,进入管理 Web 钩子项,点击存在的钩子,如 http://192.168.65.134:9080/hook,可以看到:

钩子并没有生效,并报错:
Payload URL resolved to a local network address that is implicitly blocked.
提交代码,触发 Hooks
成功提交代码,并触发钩子后,gogs 页面中显示成功信息:

drone 页面信息如下:

点击进入,可以在 GRAPH VIEW 查看详细进度及日志:

可以看到目前处于 build 阶段。完全构建完成后,页面如下:

harbor 页面中对应的镜像版本也推送成功:

相关文章:
微服务 云原生:基于 Gogs + Drone 实现 CI/CD 自动化
一般构建部署 以一个简单的前后端项目来说,分别编写前后端的 Dockerfile 文件并构建镜像,然后编写 docker-compose.yml 构建部署,启动运行。每次代码变更后都需重新手动打包、构建、推送。 一个简单的例子: 前端: 项…...
ADO.NET之SQL Server
ADO.NET是.NET平台上的一组用于访问和操作关系型数据库的API。它提供了一种以统一的方式连接到各种数据库系统并执行数据库操作的方法。现在有很多的ORM框架都是基于ADO.NET进行数据访问(比如:Entity Framework (EF)、Dapper、NHibernate 、FluentNHiber…...
Nginx负载均衡(重点)
正向代理 部署正向代理 server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { root html; index index.html index.htm; proxy_pass http://20.0.0.60:80…...
第一章 SpringBoot入门
1.SpringBoot简介 1.1.简介 Spring Boot来简化spring应用开发,约定大于配置去繁从简,just run就能创建一个独立的,产品级别的应用。 背景:J2EE笨重开发,繁多的配置、低下开发效率、复杂的部署流程、第三方技…...
JavaScript Es6_2笔记 (深入对象 + 内置构造函数 + 包装类型)+包含实例方法
JavaScript 进阶 文章目录 JavaScript 进阶深入对象构造函数实例成员静态成员 内置构造函数ObjectArray包装类型StringNumber 了解面向对象编程的基础概念及构造函数的作用,体会 JavaScript 一切皆对象的语言特征,掌握常见的对象属性和方法的使用。 了解…...
尼科彻斯定理
目录 1.题目概述 2.题解 思路分析 具体实现 1.题目概述 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。 例如: 1^31 2^335 3^37911 4^313151719 输入一个正整数m(m≤100),将…...
主数据管理案例-中国外运
1、 背景介绍及难点分析 作为世界领先的物流行业整合商、端到端的全程供应链解决方案和一站式物流服务提供商,中国外运非常重视信息化建设,先后投资建设了 300多个信息系统,为中国外运的内部管理和业务运作提供 IT 支持和保障。 由于缺乏统一…...
改进DevSecOps框架的 5 大关键技术
Markets and Markets的一项研究显示,全球DevOps的市场规模从2017年的29亿美元增加到2023年的103.1亿美元,预测期的年复合增长率(CAGR)为24.7%。人们对DevOps越来越感兴趣,因为DevOps不仅能够压缩软件的交付周期,还能提高交付的速度…...
uni-app之app上传pdf类型文件
通过阅读官方文档发现,uni.chooseFile在app端不支持非媒体文件上传; 可以使用这个插件,验证过可以上传pdf;具体使用可以去看文档 插件地址 就是还是会出现相机,这个可能需要自己解决下 实现功能:上传只能上…...
bash: sudo: command not found的解决方法 | 安装sudo
-bash: sudo: command not found的解决方法 https://www.cnblogs.com/pengpengboshi/p/16159443.html 报错 安装apt-get update报错由于没有公钥,无法验证下列签名: NO_PUBKEY A4B469963BF863CC解决办法是手动加入 (sudo可去掉)…...
电脑合上盖子无线网络不会断开
控制面板\硬件和声音\电源选项\系统设置 最终选择不会采取任何操作 选择不会采取任何操作...
【从零开始学习JAVA | 第四十篇】了解线程池
目录 前言: 线程池: 线程池的工作流程: 代码实现线程池: 任务拒绝策略: 线程池多大才算合适? 总结: 前言: 在Java编程中,线程池是一个强大的工具,它能…...
axios如何取消请求,其原理是什么?
axios 可以通过创建一个 CancelToken 来取消一个请求,基本原理是: 创建一个 CancelToken 的实例,它有一个 executor 函数,可以通过调用 executor 参数中的 cancel 函数来取消请求。在 axios 请求配置中指定 cancelToken 属性,将 CancelToken 实例传递进去。当我们需要取消请求…...
消息中间件 Asio (C++)
折腾了一上午,看到这个结果的时候泪目了兄弟闷,讲真。我的asio客户端成功收到服务端发来的消息了。虽然这确实是极其智障又简单的入门哈哈 下载独立版本 asio网络通信库新建cmake工程,CMakeLists.txt加载asioasio最简单的服务端和客户端代码…...
3.4 网络安全管理设备
数据参考:CISP官方 目录 IDS (入侵检测系统)网络安全审计漏洞扫描系统VPN(虚拟专网)堡垒主机安全管理平台 一、IDS (入侵检测系统) 入侵检测系统(IDS)是一种网络安全设备,用于监测和检测网络中的入侵行…...
前端高级面试题-JS
1. 原型 / 构造函数 / 实例 原型( prototype ): ⼀个简单的对象,⽤于实现对象的 属性继承。可以简单的理解成对象的爹。在 Firefox 和 Chrome 中,每个 JavaScript 对象中都包含⼀个__proto__ (⾮标准)的属性指向它爹(该对象的原型),可 obj.p…...
AcWing 1564:哈希 ← 只具有正增量的二次探测法
【题目来源】https://www.acwing.com/problem/content/1566/【题目描述】 将一个由若干个不同正整数构成的整数序列插入到一个哈希表中,然后输出输入数字的位置。 哈希函数定义为 H(key)key%TSize,其中 TSize 是哈希表的最大大小。 利用只具有正增量的二…...
什么是媒体代发布?媒体代发布注意事项
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 媒体代发布是指将新闻稿或其他宣传内容委托给专业的媒体代理机构或公司进行发布和推广的活动。这些机构通常拥有丰富的媒体资源、人脉和经验,能够更好地将信息传递给目标受众…...
docker版jxTMS使用指南:使用jxTMS采集数据之二
本文是如何用jxTMS进行数据采集的第二部分,整个系列的文章请查看:docker版jxTMS使用指南:4.4版升级内容 docker版本的使用,请查看:docker版jxTMS使用指南 4.0版jxTMS的说明,请查看:4.0版升级内…...
系列六、Springboot操作RocketMQ
一、同步消息 1.1、发送&接收简单消息 1.1.1、发送简单消息 /*** 测试发送简单消息*/ Test public void sendSimpleMessage() {SendResult result rocketMQTemplate.syncSend("BOOT_TOPIC_SIMPLE", "我是一个简单消息");// 往[BOOT_TOPIC_SIMPLE]主…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?
在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
