分离式 CI/CD 系统搭建 WebDAV 工件仓库

发表于 更新于

前言

现在的 GitHub Actions 以及曾经流行的很多 CI/CD 工具,一般用户会默认将 CI 和 CD 放在一条管道(或称为流水线)中,故没有构建产物(即 Artifacts:工件)的存储和管理问题。

一旦我们自己的 CI/CD 系统是各自独立的,就不得不面对工件的托管。它类似 NPM/Docker Hub,但以二进制构建产物为主,属于更为通用的仓库。WebDAV 是非常适合这种仓库的技术的一种,它建立在 HTTP 这种上层协议上,兼容性广且使用极为便利。

描述

我想我可能要进一步描述需求,因为也许对于很多人它是不存在的需求。当人们使用 GitHub Actions、GitLab CI/CD,或者将 Jenkins 等 CI 工具用于 CI + CD 的组合用途时,它的架构可能是这样的:

flowchart TB;
  构建步骤 --> 工件([工件]) --> 分发步骤

由于构建和分发步骤在一个管道中,CD 系统(或者说 CD 步骤)直接继承了 CI 的构建产物,它是不存在工件管理之说的。但一旦我们的 CI/CD 更为复杂,它就是这个样子:

flowchart TB;
  构建系统 --> 工件([工件]) -. 推送 .-> 工件仓库
  工件仓库 -- 下载 --> 目标1
  工件仓库 -- 下载 --> 目标2
  工件仓库 -- 下载 --> 目标3
  分发系统 -. 拉取任务 .-> 目标1
  分发系统 -. 拉取任务 .-> 目标2
  分发系统 -. 拉取任务 .-> 目标3
  构建系统 -. Webhook .-> 分发系统

当 CI/CD 系统各自独立时,我们就需要「工件仓库」这一设施。市面上已经有较为成熟的产品,如 JFrog 等。对于开源项目,Maven、NPM、Docker Hub 等也可以担任这个角色(非通用性)。接下来要介绍的 WebDAV 是一种十分简单的,很适合个人的工件仓库搭建方案。

WebDAV

WebDAV 是一种基于 HTTP 扩展出的协议,它针对远程文件管理而设计。通过 WebDAV 协议可以对服务器文件/目录进行基本的增删改查(包括移动、复制等),以及覆盖保护、锁定等高级功能。

搭建 WebDAV 可以使用轻量级的 Nginx(模块支持),或更全面的重量级方案 Nextcloud 等。此处我们使用 Nginx,因为我们不需要那么完整的功能。

搭建

以 Debian 12 系统为例,需安装 nginx-fullnginx-extras 这两个包。后者提供了 WebDAV 模块。

sudo apt-get install nginx-full nginx-extras

检查是否存在 WebDAV 支持:

sudo nginx -V 2>&1 | grep -o with-http_dav_module

如果输出 with-http_dav_module 则表示支持。

此处的 2>&1 是将标准错误输出重定向到标准输出,以便 grep 命令可以过滤。因为 nginx -V 默认输出到标准错误。

接下来我们创建相关目录:

sudo mkdir -m 755 /artifactory
sudo mkdir -p -m 755 /var/tmp/nginx/webdav

修改所有者:

sudo chown www-data:www-data /artifactory
sudo chown www-data:www-data /var/tmp/nginx/

生成基础验证用的用户名/密码:

username=admin
password=admin
echo "$username:$(openssl passwd -apr1 $password)" | sudo tee -a /etc/nginx/artifactory.passwd > /dev/null
切记修改上述 usernamepassword 两个变量。

万事俱备,可以直接添加 Nginx 配置了。将以下 location 片段添加你的 server 配置中:

location / {
  root /artifactory;
  client_body_temp_path /var/tmp/nginx/webdav;
  dav_methods PUT DELETE MKCOL COPY MOVE;
  dav_ext_methods PROPFIND OPTIONS;
  create_full_put_path on;

  # Basic authentication setup
  auth_basic "Restricted Access";
  auth_basic_user_file /etc/nginx/artifactory.passwd;
  client_max_body_size 1G;

  # Auto index configuration
  autoindex on;
  autoindex_exact_size off;

  # Deny all access unless authenticated
  satisfy all;
  allow all;  # This allows all authenticated users
  deny all;   # This denies all other users
  access_log /var/log/nginx/artifactory.example.com.log; # <- 注意修改日志的文件名
}

假设你将这段配置添加到绑定到 artifactory.example.com 域名的 server 下,那么请用浏览器访问此主页。在基本验证框中输入用户名和密码后,便能看到该目录下的文件/目录索引(没有文件是正常的)。

使用

因为我们的重点是和 CI/CD 集成,所以这里只介绍一些最基础的用法。更完整的 WebDAV 使用方法请自行查阅资料。

创建文件夹

我们在 WebDAV 服务器上创建一个新的文件夹:

curl -u admin:admin -X MKCOL https://artifactory.example.com/new_folder

刷新浏览器的索引页面即可看到效果。

再次强调,这里的 admin:admin 是示例用户名/密码,你应该修改并替换为你自己的。

上传文件

将本地的 app-bin.tar.gz 文件上传到 new_folder 目录下:

curl -u admin:admin -T app-bin.tar.gz https://artifactory.example.com/new_folder/

删除文件

把刚刚上传的文件删掉:

curl -u admin:admin -X DELETE https://artifactory.example.com/new_folder/app-bin.tar.gz
如果你要删除文件夹,必须后缀 /,否则 Nginx 会返回 419 错误。

从以上可以发现 WebDAV 的使用是非常容易的,只是一些简单的 HTTP 请求。部分请求方法可能不属于 HTTP 协议规范,但 HTTP 的发起本身并没有变得复杂。

CI/CD 集成

检查你所使用的 CI 和 CD 工具是否存在 WebDAV 插件。如果没有,那么你可以直接使用 curl 命令来实现上传/下载工件。即使是自行开发插件,工作量和难度都不大。

这里是一个 WebDAV 插件的例子,它是一个基于声明式配置的 CI 工具的一部分:

push-to-artifactory:
  image: vividboarder/drone-webdav
  settings:
    file: "{bin/app-arm64,bin/app-amd64}"
    username: admin
    password: admin
    destination: https://artifactory.example.com/app/

当我们集成 WebDAV 以后,便不需要再挂载任何本地/远程文件系统目录。因为工件可以基于网络推送和拉取。

结束语

如果你有更复杂且确实必要的功能,如版本控制,本文介绍的方案还不够。但我不认为是 WebDAV 的不足,它毕竟是一种通用的方案。你完全可以定制开发自己的 WebDAV 后端,让其支持版本管理。

顺带一提 WebDAV 也是很多网盘支持的协议,在远程存储管理方面它非常适合作一种开放给用户使用的技术。

作者头像 一点点入门知识 打赏作者
本文由作者按照 CC BY 4.0 进行授权
分享: