--- title: "Drone部署和与gitea的集成" date: 2023-08-07T19:09:08+08:00 --- 原本的博客是直接使用的非开发模式的hugo server,但随着博客内容增多,内存占用巨大,经历昨晚内存溢出至交换区使服务器超高磁盘IO,所有服务无响应后决定将静态页面直接由原有反向代理的nginx直接托管 为了便于专注创作,在gitea上引入drone CI来做简单的持续集成变得有所必要,毕竟每次提交后都要手动pull和构建远远不够优雅:D 本文记录drone CI的docker-compose 方式部署并与已经完成部署的gitea docker集成,官方文档不推荐此种方式部署,也不建议gitea和drone部署在一台服务器上(预算不足暂出此策) 首先需要在gitea上创建OAth2应用令牌并设置应用的重定向URL ![](../../images/%E6%9D%82%E7%89%A9/Drone%E9%83%A8%E7%BD%B2%E5%92%8C%E4%B8%8Egitea%E7%9A%84%E9%9B%86%E6%88%90/OAth2.png) 重定向URL必须为http(s)://域名/login形式,视ssl情况是否有s 生成用于Drone的server和runner间通信的通信密钥 ```bash openssl rand -hex 16 ``` drone-server的docker-compose文件 ```yaml version: "3" services: drone-server: image: drone/drone:2.13.0 container_name: drone-server restart: always ports: - "7500:80" volumes: - ./data:/data environment: - DRONE_GITEA_SERVER=#Gitea 服务器地址,例如 https://gitea.inksoul.top。注意填写准确的 http(s) 协议,否则你会看到来自 Gitea 的错误报告:unsupported protocol scheme - DRONE_GITEA_CLIENT_ID=#Gitea OAuth 客户端ID - DRONE_GITEA_CLIENT_SECRET=#Gitea OAuth 客户端密钥 - DRONE_RPC_SECRET=#在准备工作中使用 openssl rand -hex 16 生成的共享密钥。这个密钥用于验证 Drone Server 和 Runner 之间的 RPC 连接。因此,在 Server 和 Runner 上都必须使用相同的密钥 - DRONE_SERVER_HOST=#访问 Drone 时所用的域名或 IP 地址。如果使用 IP 地址,还应该包含端口 - DRONE_SERVER_PROTO=#设置服务器的协议,使用:http 或 https。 默认为 https - DRONE_USER_CREATE=#管理员配置,这里的管理员用户名是Git仓库的用户名,不一定是Git仓库的管理员,只要是Git仓库的用户即可,例如 username:inksoul,admin:true ``` 在完成域名解析绑定和nginx中反向代理设定后,就可以拉取容器并启用了 nignx反向代理则在官方文档中有指出 ```conf location / { proxy_pass http://localhost:port/; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; proxy_http_version 1.1; proxy_buffering off; proxy_pass_request_headers on; } ``` 完成准备后即可运行启动drone-server ```bash docker-compose up -d ``` 随后可以安装负责流水线的droen-runner ```yaml version: "3" services: drone-runner: image: drone/drone-runner-docker:latest restart: always container_name: drone-runner volumes: - /var/run/docker.sock:/var/run/docker.sock:rw environment: - DRONE_RPC_PROTO=#访问Drone时的网络协议,http或https - DRONE_RPC_HOST=#访问 Drone 时所用的域名或 IP 地址。如果使用 IP 地址,还应该包含端口 - DRONE_RPC_SECRET=#在准备工作中使用 openssl rand -hex 16 生成的共享密钥。这个密钥用于验证 Drone Server 和 Runner 之间的 RPC 连接。因此,在 Server 和 Runner 上都必须使用相同的密钥 - DRONE_RUNNER_CAPACITY=2#同时运行数量 - DRONE_RUNNER_NAME=runner# runner的名字 ``` 安装完成后访问drone-server中的域名即可自动跳转授权然后正常使用了 在这几步中便踩了坑 docker-compose中环境变量设置在等于号后面不要输入空格再接参数,尤其在DRONE_GITEA_SERVER这一项,必须保证有http(s)://网络头,否则容易产生404无法跳转自动授权 --- 如出现404,检查URL形式,是否存在不恰当的%20(空格在URL的编码)存在的话请按上一个点检查docker-compose中环境变量的配置,如URL确保无误,可以直接访问drone-server域名的/后面的URL,跳过drone-server提供的自动跳转,完成直接授权,授权后404情况就会消失 实在不懂可以找一个github授权的网页查看URL结构,就可以模仿github授权的URL结构在404页面的URL中截取 ![](../../images/%E6%9D%82%E7%89%A9/Drone%E9%83%A8%E7%BD%B2%E5%92%8C%E4%B8%8Egitea%E7%9A%84%E9%9B%86%E6%88%90/OAthURL.png) --- 一切正常地部署完成后,便可以在drone的首页看到自己在gitea上的所有项目,可以查看build情况和设置对应的选项 ![](../../images/%E6%9D%82%E7%89%A9/Drone%E9%83%A8%E7%BD%B2%E5%92%8C%E4%B8%8Egitea%E7%9A%84%E9%9B%86%E6%88%90/drone%E9%A6%96%E9%A1%B5.png) 这里展示的是这个便是这个博客在我的drone上的设置 ![](../../images/%E6%9D%82%E7%89%A9/Drone%E9%83%A8%E7%BD%B2%E5%92%8C%E4%B8%8Egitea%E7%9A%84%E9%9B%86%E6%88%90/drone%E8%AE%BE%E7%BD%AE.png) 单有流水线设置还不够,流水线流程的定义还需要在项目中使用yaml文件来定义,对应的文件就在drone上设置 要定义流水线,要先了解drone的工作过程 drone在收到来自gitea的webhook调用后,根据yaml中定义拉取容器镜像在容器中完成定义的任务 webhook在完成drone的集成时就由drone在对应gitea项目下自动创建,我的需求显然是每次我push新内容后drone自动构建,因此webhook中也要做些修改 如图,我只选择了一些会导致博客内容发生改变的选项 ![](../../images/%E6%9D%82%E7%89%A9/Drone%E9%83%A8%E7%BD%B2%E5%92%8C%E4%B8%8Egitea%E7%9A%84%E9%9B%86%E6%88%90/webhook%E8%AE%BE%E7%BD%AE.png) 既然drone是在容器内执行任务,那么容器镜像则十分重要,为了确保足够轻量(内存溢出的教训印象深刻),我选择了自行配置一个镜像,使用alpine + git + hugo + rsync来配置,尽可能减少容器占用 Dockerfile如下 ```Dockerfile FROM alpine RUN apk update && \ apk add git && \ apk add rsync && \ apk add hugo && \ hugo version ``` 自行构建后如果发现测试时容器exit(0),这是正常情况,由于容器内没有前台应用,使得容器在完成hugo version指令后就进入空闲状态,然后自动退出(节省资源),如果想保持可以在Dockerfile最后运行一个交互式终端 如果不想自行构建,也可以在docker hub上直接pull ```bash docker pull inksoul/hugo-rsync:latest ``` 镜像大小仅30.3MB,容器占用约87.7MB,会在drone的任务完成后自动销毁 流水线配置文件如下,需要根据自己的情况修改声明数据卷中的宿主机路径,通常为静态网页的存放的地方 ```yaml kind: pipeline type: docker name: blog-publish clone: disable: false # 启用代码拉取 steps: - name: build image: inksoul/hugo-rsync depends_on: [clone] # 依赖的步骤, volumes: #挂载数据卷 - name: blog path: /data #容器内 commands: - hugo - rsync -a --delete --exclude '.user.ini' public/ /data volumes: #声明数据卷 - name: blog host: path: /Blog/public # 宿主机 ``` 流水线配置依旧存在一些问题,每次build都需要clone一遍,导致耗时比较长(尤其大型项目),下一步考虑引入drone-volume-cache,缓存项目来加快速度 整体下来轻量化十分明显,原来溢出的内存现在只占用了1GB(不止nginx + gitea + drone三项服务),也节省了不少服务器的开支,毕竟云服务对于我这种学生党还是比较贵的