前言
很久之前,有个云服务器,上面挂着自己的 Blog,每次发布代码的时候,都需要手动到服务器上 pull 代码,很是麻烦。
于是,折腾了一下 Gitee 的 Hook,实现了自动部署的功能。
一些答复
为什么不用比较成熟的工具?比如:Jenkins、CI/CD。
1、资源问题,本身就一台小服务器,没那么多资源搞这个。
2、自己搞个简单的,免费,香。
是否会停服?
会有短暂停服,如果不像停服,需要改造一下策略。
是否支持多副本?
不支持,因为作者的需求比较简单,未实现多副本的方案。
环境
- Docker
- PHP
- Nginx(需要支持Lua模块)
- Lua
示例代码
具体流程图
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wa9XEBo8-1630649595017)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ba3e75d5-1b50-45c7-964b-59beeab193e3/Untitled_Diagram.drawio_(1)].png)](https://i-blog.csdnimg.cn/blog_migrate/25da8ca82f1795f0c5af83dcee4ce490.png)
具体实现
项目结构改造
这里的目的是将项目结构都改造成一致,方便后续脚本的统一。
.
├── src // 项目目录
└── version.txt // 项目版本
宿主机安装Git
因为需要拉取云端代码,需要 git。
配置自动化项目
这个项目可以放到代码仓库里。
本文将项目放在了 /src 目录下。
具体结构和释义如下:
/src
├── dockers
│ ├── docker-compose.yml // 使用Docker compose编排容器
│ ├── mysql // 存放mysql数据的目录
│ ├── redis // 存放redis数据的目录
│ ├── lua
│ │ └── hook.lua // 这是Nginx接收到webhook之后,执行的lua脚本
│ ├── projects
│ │ ├── api.demo.com
│ │ │ ├── Dockerfile // 生成镜像和容器的Dockerfile
│ │ │ └── publish.sh // 发布脚本,会拉取代码,根据Dockerfile创建镜像和容器
│ │ └── admin.demo.com
│ │ ├── Dockerfile
│ │ └── publish.sh
│ └── nginx
│ ├── nginx.conf // 重写了nginx.conf,用于支持后续的项目配置,这个会在一开始替换 /etc/nginx/nginx.conf
│ ├── webhook.conf // webhook的nginx conf,里面会指定需要执行的lua脚本
│ └── api.demo.com.d
│ └── api.demo.com.conf // api.demo.com的nginx conf
├── api.demo.com // 具体的项目目录
│ ├── src // 代码目录
│ └── version.txt // 项目版本,构建镜像时会使用
└── admin.demo.com // 具体的项目目录
├── src // 代码目录
└── version.txt // 项目版本,构建镜像时会使用
宿主机安装Nginx
因为需要构建容器,所以直接在宿主机上安装了 Nginx,用于转发请求。
需要安装 lua 模块。
安装好之后,将自动化配置中的 nginx.conf 替换默认的 nginx.conf。
宿主机安装Docker和Docker compose
这个毋庸置疑了。
安装好之后,在 /src/dockers 目录下,运行 docker compose up -d。
配置Gitee
在项目的 管理→WebHooks 下添加WebHook。

编写Nginx Lua脚本
为了能够适应多个项目,这里会通过路由来辨别不同的项目。
大致结构是:http://webhook.demo.com/项目别名。
同时,每个项目都有回调时都有自己的密钥。
所以我们需要先定义项目和域名的映射表,项目和密钥的映射表。
-- 需要修改域名和对应别名
local mapping = {
api = "api.demo.com",
admin = "admin.demo.com"
}
-- 每个项目的密钥
local password = {
api = "E491B741843DA372DE61FCF8EFBB5252",
admin = "E491B741843DA372DE61FCF8EFBB5252"
}
接下来是判断请求和项目、密钥是否匹配。
可以先参考一下 Gitee 的请求头信息,如果是其它平台,则需要自行研究。
Request URL: http://webhook.demo.com/api
Request Method: POST
Content-Type: application/json
User-Agent: git-oschina-hook
X-Gitee-Token: E491B741843DA372DE61FCF8EFBB5252
X-Gitee-Timestamp: 1591321794260
X-Gitee-Ping: false
X-Gitee-Event: Push Hook
X-Git-Oschina-Event: Push Hook
可以看出,需要判断路由对应的项目是否存在,密钥是否存在。
local project = ngx.var.request_uri
project = string.gsub(project, "/", "")
if (not mapping[project]) then
ngx.say('error project')
ngx.log(ngx.ERR, 'webhook: error project')
return 0
end
if (not password[project]) then
ngx.say('error project')
ngx.log(ngx.ERR

本文介绍了如何通过配置Gitee的WebHook实现基于Docker的自动部署,利用Nginx+Lua脚本来处理WebHook请求,确保只有master分支更新并验证密钥后才执行部署,同时提供了项目结构调整、Dockerfile和发布脚本编写等详细步骤。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



