首先来说需要实现一种什么效果
当我们写完代码打上 git tag 推送到 GitHub 仓库时自动触发 GitHub actions 工作流,将项目打包并自动发布更新
要完成以上步骤我们需要做以下准备:
- 一个云服务器并安装 docker
- 一个 gf 项目并配置好 docker 打包的相关配置
- 使用 GitHub actions 在 git tag 更新时自动打包发布应用
云服务器安装 docker
作者是 2c2g 的阿里云主机官方提供了 docker 的安装文档
阿里云服务器安装 docker
docker 常用命令
本篇文章中仅会涉及如下 docker 命令基本满足日常使用
docker run <image>
:从指定的镜像运行一个容器。docker ps
:列出正在运行的容器。docker ps -a
:列出所有的容器,包括停止的容器。docker images
:列出本地的镜像。docker pull docker.io/vaebe/kkdl:v0.1.0
:从远程仓库拉取镜像到本地。docker build <path_to_Dockerfile>
:使用 Dockerfile 构建镜像。docker rm <container>
:删除指定的容器。docker rmi <image>
:删除指定的镜像。docker stop <container>
:停止指定的容器。docker start <container>
:启动已经停止的容器。docker exec <container> <command>
:在运行的容器中执行命令。docker logs <container>
:查看容器的日志。docker inspect <container>
:查看容器的详细信息。
gf 项目 docker 打包配置
本文以kkdl 短链项目为例
修改 Dockerfile 文件
如下图所示修改 manifest/docker/Dockerfile
增加映射端口 EXPOSE 6001
修改 hack/config.yaml 文件
将 docker/tagPrefixes
修改为 docker hub 的用户名
将 template-single
改为对应的项目名称,这两个地方组成了打包后 docker 镜像的名称
如果不改打包后镜像名称应为 my.image.pub/my-app/template-single
打包 docker 镜像
gf 打包 docker 的命令会获取 git tag 作为镜像的标签所以我们先使用 git tag v0.2.0
打一个标签
make image
打包
执行 make image
进行打包,成功后输出如下
如果 Git 仓库的状态是干净的(没有未提交的更改),则 tag
变量的值保持不变;如果 Git 仓库的状态是脏的(有未提交的更改),则 tag
变量的值在原来的标签基础上添加 .dirty
后缀。
将所有代码提交后在进行打包标签则会变成
具体逻辑代码在 hack/hack.mk
中查看
make image.push
打包发布
除了 make image
命令外还有一个 make image.push
命令, image.push
命令会在镜像打包完成后推送到 docker hub 上
要成功执行 image.push
1. 本地 docker 需要登录 2. 需要在 docker hub 上新建对应的仓库否则会抛出错误
推送 docker hub 失败
推送 docker hub 成功
查看 docker hub 发现镜像已成功上传
至此前期准备工作已经完成,本地验证 docker 镜像发布到 docker hub 流程正常!
使用 GitHub actions 自动部署
GitHub Actions 是 GitHub 提供的一种自动化工作流程服务,可以在 GitHub 存储库中设置和执行自定义的自动化任务。使用 GitHub Actions,可以根据触发事件(如提交代码、创建问题或发布版本)来执行各种操作,如运行测试、构建和部署应用程序、自动化代码审核等。
设置执行 actions 所需的相关变量
打开仓库的 settings
找到 secrets/actions 进行设置
CONFIG
这里将配置文件 config.yaml 转换为 json 字符串存入,然后打包的时候将 json 字符串在转为 config.yaml
这样做的原因是 config 文件是不上传的,打包的时候会缺失这个文件!
暂时也没想到好的处理方式,如果有话可以评论区留言告诉我
DOCKERHUB_TOKEN
点击头像选择 My Account
选择左侧 security
点击 New Access Token
填写对应信息,注意权限选择
点击 Generate
生成,然后点击 Copy
复制对应 token
服务器相关信息根据实际自行填入
编写 GitHub actions
在项目根目录下创建 .github/workflows/deploy.yml
文件夹及文件
actions 名称及触发条件
name: Build and Deploy Docker Image
on:
push:
tags:
- 'v*' # 当有以 'v' 开头的 tag 被推送时触发
完整配置
name: Build and Deploy Docker Image
on:
push:
tags:
- 'v*' # 当有以 'v' 开头的 tag 被推送时触发
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # 检出完整的git历史记录
- name: Ensure directory exists
run: mkdir -p $GITHUB_WORKSPACE/manifest/config # 确保目录存在,用于存放配置文件
- name: Set Config File
run: |
printf '%s' ${{ secrets.CONFIG }} | python -c 'import json, sys, yaml; print(yaml.dump(json.loads(sys.stdin.read())))' > $GITHUB_WORKSPACE/manifest/config/config.yaml # 设置配置文件,将环境变量中的 JSON 字符串格式化为 YAML 格式
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.20' # 设置 Go 版本为 1.20
- name: Install gf-tool
run: |
wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH) && chmod +x gf && ./gf install -y && rm ./gf # 安装 gf 工具
- name: Login to Docker Hub
run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin # 登录到 Docker Hub
- name: Build and push Docker image
run: |
make image.push # 构建并推送 Docker 镜像
- name: Get version
id: get_version
run: echo ::set-output name=VERSION::${GITHUB_REF/refs/tags//} # 获取版本号,去掉前缀 'refs/tags/'
- name: Deploy to server
uses: appleboy/ssh-action@master
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
GIT_TAG: ${{ steps.get_version.outputs.VERSION }} # 使用之前步骤中获取的版本号
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
port: 22
envs: DOCKERHUB_USERNAME,GIT_TAG
script: |
# 删除所有指定名称的镜像
docker rmi $(docker images -q $DOCKERHUB_USERNAME/kkdl)
# 拉取 Docker 镜像
docker pull docker.io/$DOCKERHUB_USERNAME/kkdl:$GIT_TAG
# 检查容器是否存在,停止并删除已存在的容器,然后运行新的容器
docker container ls -a | grep -q "kkdl" && docker stop kkdl && docker rm kkdl
docker run -d --name kkdl -p 6001:6001 $DOCKERHUB_USERNAME/kkdl:$GIT_TAG
步骤说明
Checkout code
检出代码,用于后续的构建和部署。
Ensure directory exists
如果目录不存在的话就创建,确保目录存在,用于存放配置文件。
Set Config File
$GITHUB_WORKSPACE
检出代码的所在的目录
将上边设置的 secrets.CONFIG
JSON 字符串格式化为 YAML 格式放入到项目对应文件夹内
Set up Go
设置 Go 版本为 1.20, 需要使用 go 进行打包项目
Install gf-tool
goframe项目,安装 gf 工具,用于后续操作。
Login to Docker Hub
使用 Docker Hub 的凭据登录到 Docker Hub,以便推送镜像。
Build and push Docker image
使用 gf 工具构建并推送 Docker 镜像到 docker hub。
Get version
获取版本号,去掉前缀 ‘refs/tags/’,云服务器无法直接使用 GITHUB_xxxx
的变量,获取后下一步使用
Deploy to server
将需要使用的环境变量通过配置传递后使用
部署到服务器,包括拉取 Docker 镜像、停止并删除已存在的容器,然后运行新的容器。
当有 git tag 推送到远程仓库的时候就会触发 GitHub actions 自动部署的脚本执行
总结
本文实践了如何将 gf 项目通过 GitHub actions 将项目打包成 docker 镜像并自动更新服务
学习了 docker 的常用命令如 拉取、推送、删除、查看、创建镜像的相关操作
学习了如何编写一个 GitHub actions
往期文章
- 手摸手开发一个全栈项目
- 从零到一建立属于自己的前端组件库
- 求求你们了,对自己代码质量有点要求!
- 不要用vue2的思维写vue3
- openlayers 实战离线地图
- 一个开源的leafletjs示例项目
- vue3 JSX 从零开始
- 手摸手,配置项目中全局loading
- vue + element-ui动态主题及网站换肤2021,亲测可用!!!
- vue3+elementPlus主题动态切换2022,亲测可用!
- go ➕ “蓝兔支付”实现个人网上支付
原文链接:https://juejin.cn/post/7352555529104425012 作者:唐诗