效果预览
只需要在软件列表文件中添加你想要入库的 github 链接地址即可,比如:

当软件列表文件更新后会生成带有索引目录的 APT 仓库

核心优势
- 跨平台分发:GitHub Pages(国际) + 阿里云 OSS(国内)双通道
- 军工级安全:GPG 签名 + 密钥分层管理
- 极速构建:单次构建耗时 < 2 分钟(实测数据)
- 零成本起步:GitHub Actions 免费配额
如果你是专家,你可以直接 Fork 我的仓库改改就能用:https://github.com/qlAD/aptRepo
前置知识
APT 仓库如何工作
首先要明白 APT 仓库其实就是一个规范整理的文件夹,里面包含了软件包和索引文件。
具体的目录结构如下:
.
├── conf
│ └── distributions
├── db
│ ├── checksums.db
│ ├── contents.cache.db
│ ├── packages.db
│ ├── references.db
│ ├── release.caches.db
│ └── version
├── dists
│ └── sid
│ ├── InRelease
│ ├── main
│ │ └── binary-amd64
│ │ ├── Packages
│ │ ├── Packages.gz
│ │ └── Release
│ ├── Release
│ └── Release.gpg
└── pool
└── main
└── c
└── clash-verge
└── clash-verge_2.2.3_amd64.deb
我们需要做的就是整理好这些文件放到一个可以被访问的地方,并且让 APT 客户端知道这个地方。
整理文件很简单,有一个自动化的工具叫做 reprepro
,它会自动帮你生成这些文件。
然后把这些文件放到一个可以被访问的地方,比如 Web 服务器、GitHub Pages 或者阿里云 OSS。
最后在 /etc/apt/sources.list.d
中添加一个 .sources
文件,告诉 APT 客户端这个地方在哪里。
# /etc/apt/sources.list.d/qladgk.sources
Types: deb
URIs: https://apt-repo.qladgk.com/debian
Suites: sid
Components: main
Signed-By: /etc/apt/keyrings/qladgk.asc
然后当你运行 apt update
的时候,APT 客户端就会去这个地方下载索引文件,然后根据索引文件去下载软件包。
GPG 签名
GPG 密钥就好像互联网上的另一个自己,私钥就像是你的身份证,公钥就像是你的名片。
公钥可以随意发给别人,私钥必须要保管好。
APT 仓库的软件包都需要进行 GPG 签名,这样才能保证文件的完整性和安全性,或者直接对整个仓库进行签名。
如果你不进行签名,APT 客户端会报错,提示你这个仓库不可信。
如果你泄露了私钥,别人可以通过你的私钥对软件包进行签名,这样就可以伪造软件包,APT 客户端会认为这个软件包是可信的。
部署搭建步骤
1. 生成 GPG 密钥对
首先需要安装 GPG 工具,如果你使用的是 Debian 或 Ubuntu,可以直接使用以下命令安装:
sudo apt install gnupg
接下来生成 GPG 密钥对,使用以下命令:
gpg --full-generate-key
在生成过程中,你需要选择密钥类型、密钥大小、有效期等信息。
其中密钥类型包括如下选项

其中默认的 ECC(椭圆曲线密码学)提供了更高的安全性与更短的密钥长度,但它在某些旧系统中可能不被支持
所以这里就选择第一项 RSA 和 RSAi 就行
然后密钥大小建议选择 4096 位,这样可以提供更高的安全性
有效期可以根据需要设置,建议设置为 1 年以上,因为 Debian 的 apt 会警告一年内即将过期的密钥,这里我选的是永不过期
当所有信息填完之后会打开密码输入框来加密你的密钥,有密码的好处是即使泄露了私钥,别人也不能通过一个带密码的私钥来签名
全部截图如下:

到此密钥对生成成功,接下来需要把密钥对导出,然后私钥给到 Github Action 让它帮我们自动签名,把公钥暴露在网络上供人使用
2. 导出密钥对
首先我们可以查看刚才创建的密钥对
gpg --list-secret-keys
确认密钥存在后,使用 ASCII 的形式导出
因为我们要把私钥复制到 Github Action 中的环境变量里,所以要用 ASCII 这种方便复制的形式
gpg -a -o public-key.asc --export 你的密钥中的邮箱 #导出公钥
gpg -a -o private-key.asc --export-secret-keys 你的密钥中的邮箱 #导出私钥
导出密钥的时候需要输入你刚才设置的密码
-a 为 –armor 的简写,表示密钥以 ASCII 的形式输出,不加则默认以二进制的形式 gpg 输出
-o 为 –output 的简写,指定写入的文件
全部截图如下:

密钥创建并导出之后就可以开始设置 Github 仓库
3. 创建 GitHub 仓库
由于我们要使用 GitHub Actions 来自动化构建 APT 仓库,并且会用到 Github Pages 来搭建仓库的访问地址,所以首先需要一个 GitHub 仓库来存放我们的代码和配置。
首先在 GitHub 上创建一个新的仓库,比如 apt-repo
。

然后来到仓库的设置页面,允许 Actions 的一些权限

接着设置一些环境变量,如下

其中前三个与阿里云的 OSS 相关,如果你没有阿里云的 OSS 可以不设置
后两个是 GPG 的私钥和密码,复制私钥和输入私钥的密码就行
4. 配置 GitHub Actions
在仓库根目录下创建一个 .github/workflows
目录,然后在里面创建一个 update-repo.yml
文件。
内容如下:
name: Update APT Repository
on:
workflow_dispatch:
push:
paths:
- "packages.list"
jobs:
build-repo:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Environment
run: |
sudo apt-get update
sudo apt-get install -y reprepro gnupg wget
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Fetch Packages
run: |
mkdir -p downloaded_packages
./scripts/fetch-packages.sh
- name: Build Repo
run: |
./scripts/setup-reprepro.sh
- name: Upload APT Repo to Aliyun OSS
uses: fangbinwei/aliyun-oss-website-action@v1
with:
accessKeyId: ${{ secrets.ACCESS_KEY_ID }}
accessKeySecret: ${{ secrets.ACCESS_KEY_SECRET }}
bucket: ${{ secrets.ACCESS_BUCKET_NAME }}
endpoint: oss-cn-shanghai.aliyuncs.com
folder: ./gh-pages
- name: Generate Directory Listings
uses: jayanta525/github-pages-directory-listing@v4.0.0
with:
FOLDER: ./gh-pages
- name: Upload artifact
uses: actions/upload-pages-artifact@v3.0.1
with:
path: "./gh-pages"
deploy-index:
needs: build-repo
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4.0.0
支持手动触发和当 packages.list
有更新后自动触发,当然你也可以设置每周触发一次,但是频率不要太高
如果你不需要阿里云的 OSS 部署就将这部分删掉
- name: Upload APT Repo to Aliyun OSS
uses: fangbinwei/aliyun-oss-website-action@v1
with:
accessKeyId: ${{ secrets.ACCESS_KEY_ID }}
accessKeySecret: ${{ secrets.ACCESS_KEY_SECRET }}
bucket: ${{ secrets.ACCESS_BUCKET_NAME }}
endpoint: oss-cn-shanghai.aliyuncs.com
folder: ./gh-pages
其中还用到了两个 action 的模板,如果有想了解的自己去看
5. 编写脚本
./scripts/fetch-packages.sh
用于下载软件列表 packages.list
中特点架构的软件包
#!/bin/bash
REPO_LIST="packages.list"
TMP_DIR="downloaded_packages"
while IFS= read -r repo_url; do
repo_owner=$(echo "$repo_url" | cut -d'/' -f4)
repo_name=$(echo "$repo_url" | cut -d'/' -f5)
# 仅下载 amd64 架构的包
assets=$(curl -s "https://api.github.com/repos/${repo_owner}/${repo_name}/releases/latest" |
jq -r '.assets[] | select(.name | test(".*_amd64\\.deb$")) | .browser_download_url')
for asset_url in $assets; do
wget -P "$TMP_DIR" "$asset_url"
done
done < "$REPO_LIST"
packages.list
文件中每一行对应一个 Github 仓库
./scripts/setup-reprepro.sh
用来创建 APT 仓库所需要的目录结构
#!/bin/bash
REPO_DIR="gh-pages/debian"
CONF_DIR="repo-config"
# 清理旧数据
rm -rf "$REPO_DIR" "$CONF_DIR"
# 初始化配置目录
mkdir -p "$REPO_DIR"
mkdir -p "$CONF_DIR"/conf
Codename="sid"
Suite="$Codename"
# 生成核心配置文件
cat > "$CONF_DIR"/conf/distributions <<EOF
Origin: apt-repo
Label: apt-repo
Description: Self APT Repository
Codename: $Codename
Suite: $Suite
Architectures: amd64
Components: main
SignWith: yes
EOF
# 导入软件包
for deb in downloaded_packages/*.deb; do
# 导入到仓库
reprepro -V -b "$CONF_DIR" -S misc includedeb "$Codename" "$deb"
done
# 生成元数据
reprepro -b "$CONF_DIR" export "$Codename"
# 合并文件到发布目录
rsync -a "$CONF_DIR"/ "$REPO_DIR/"
关于 distribution 中 codename/component/suite 这些术语,debian 官方是有解释
一般 codenam 与 suite 一致,都是各个版本的代号,比如 bionic
、xenial
、trixie
另外别忘了给脚本加上可执行权限
6. Github Pages
接下来在仓库的设置页面,开启 GitHub Pages 功能,选择 Actions
作为源

最后别忘了你还要上传一个 packages.list
文件
最后结构应该如下所示

然后只用运行 Action 就会自动完成所有事
验收成果
查看索引网页
本身的 APT 仓库是只能被 apt line 识别,没有索引。但是我在 action 里面加了搭建索引的步骤
只需要在浏览器访问你的 pages 地址即可,因为我自定义了域名所以是 https://repos.qladgk.com/debian/
你应该会看到如下界面

其实索引并不重要,只是方便网页查看而已
导入这个 apt 仓库
首先要接受别人的仓库你需要下载别人仓库提供的公钥,如果你还不知道公钥是什么,就往前翻
我的公钥的直链下载链接在 https://apt-repo.qladgk.com/public-key.asc
所以我可以直接用命令行下载
sudo apt-get update
sudo apt-get install ca-certificates curl #必须安装的工具
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://apt-repo.qladgk.com/public-key.asc -o /etc/apt/keyrings/qladgk.asc
sudo chmod a+r /etc/apt/keyrings/qladgk.asc
这里将下载的公钥存放在 /etc/apt/keyrings 也是 Debian 官方推荐的,现在很少用 apt-key add
这个命令,也不推荐放在 /etc/apt/trusted.gpg.d
或者 /usr/share/keyrings/
然后创建软件源管理文件,推荐使用 DEB822 格式 /etc/apt/sources.list.d/xxxxx.sources 来管理软件源
创建 /etc/apt/sources.list.d/qladgk.sources
文件,内容如下:
Types: deb
URIs: https://repos.qladgk.com/debian
Suites: sid
Components: main
Signed-By: /etc/apt/keyrings/qladgk.asc
其中的 Suites、Components 按照你的仓库来填写
测试安装软件
接下来执行 apt update
你就能看见 apt 已经获取到了这个仓库的数据
完整截图如下:

然后尝试安装你仓库里的软件包

验证仓库签名
由于我在脚本中选择的是对整个仓库进行签名,所以需要下载仓库的密钥进行核对
在如图的位置中下载仓库签名

然后通过 gpg 验证
gpg --verify Release.gpg Release
完整截图如下:

结尾
其实只要是个标准的 apt 仓库都能通过这种方法进行管理,比如说 Docker、Chrome、Vscode

如果你想把旧版本的 sources.list 换成 xxxx.sources 可以通过如下命令
apt modernize-sources
不用担心你会丢失原有的 .list 他只是被重命名成了 .list.old
最后,如何用包管理器快速方便的获取到你想要的包呢?把 Debian 换成 Arch 就行 :)