fdroidserver 2.4.5 配置参数详解
fdroidserver 2.4.5 config.yml 参数族逐项实测详解:仓库身份、归档策略(archive_older 双向移动与 keepversions 加倍取证)、签名密钥、发布部署、镜像高可用与进阶参数,每项均附实测回显或源码取证。
fdroidserver 2.4.5 配置参数详解
目标:把 fdroidserver 2.4.5 的 config.yml 参数族讲透。本文对仓库身份、归档策略、签名密钥、发布部署、镜像高可用与进阶参数逐项给出2026-10-28 实测回显或源码取证,可复核、可直接套用。安装与环境准备见《Ubuntu 22.04 安装 fdroidserver 2.4.5 指南》,生态背景见《F-Droid 介绍与选型指南》。
本系列另一篇实操文档:命令族详解与备份恢复闭环见《fdroidserver 2.4.5 常用 CLI 命令与工具详解》。
实测环境:Ubuntu 22.04,fdroidserver 2.4.5(PyPI),演示仓库 /root/repo-c1(含 org.fdroid.fdroid 2000052 与 org.schabi.newpipe 998/999 共 3 个 APK),仓库网页根通过 8149 端口提供(http://10.89.73.2:8149/c1/repo)。
一、config.yml 从哪来、怎么加载
fdroid 的所有参数都收敛在一个 YAML 文件 config.yml,来源有三:
-
fdroid init生成:实测在空目录执行 init 生成 18446 字节的 config.yml,但其中只有 6 个实体键,其余全是注释态模板:sdk_path: /opt/android-sdk repo_keyalias: fdroid-server keystore: keystore.p12 keystorepass: lje//cM3…(实测生成的随机密码,此处脱敏) keypass: lje//cM3…(同上) keydname: CN=fdroid-server, OU=F-Droid -
官方完整样例:安装后随包附带
/usr/local/share/doc/fdroidserver/examples/config.yml,实测 470 行全部为注释态(YAML 解析结果为空),收录约 70 个参数键——这就是参数全集的权威清单,复制为 config.yml 后按需取消注释。 -
镜像清单特例:mirrors 参数既可写在 config.yml,也可单独放
config/mirrors.yml,二选一(源码 index.py 中明确处理;两处同时设置会报mirrors set twice)。
💡 init 生成的 config.yml 里 repo_url、repo_name 等是注释态(
# repo_url: https://MyFirstFDroidRepo.org/fdroid/repo),新仓库必须先取消注释并按实际环境填写,否则索引里的仓库地址为空。
二、参数总览(按功能族)
| 功能族 | 代表参数 | 本文验证深度 |
|---|---|---|
| 仓库身份 | repo_url, repo_name, repo_description, repo_icon, repo_maxage | 实测(索引回读取证) |
| 归档策略 | archive_older, archive_url, archive_name | 实测(双向移动实证) |
| 签名密钥 | keystore, keystorepass, keypass, repo_keyalias, keydname, gpgkey | 实测(keytool/gpgsign) |
| 发布部署 | serverwebroot, local_copy_dir, servergitmirrors, github_releases, awsbucket, rclone_config | 实测(deploy 行为) |
| 镜像高可用 | mirrors(或 config/mirrors.yml) | 实测(索引生成与报错) |
| 推送安装 | install_list, uninstall_list | 实测(index-v2 取证) |
| 发布审计 | binary_transparency_remote | 实测(update/btlog 行为) |
| 分仓模式 | per_app_repos | 实测(含已知边界) |
| 质量扫描 | scan_binary, refresh_scanner, scanner_signature_sources, lint_licenses | 机制说明 |
| 元数据规范 | char_limits, current_version_name_source, release_notes_prepend | 机制说明 |
| 构建环境 | sdk_path, ndk_paths, java_paths, cachedir, build_server_always, gradle, ant, mvn3 | 机制说明(构建篇范围) |
三、仓库身份族:决定客户端看到什么
这一族参数直接写进索引文件,是客户端「关于仓库」页面显示的内容。实测在 config.yml 设置 repo_url: http://10.89.73.2:8149/c1/repo、repo_name: Quzuo Demo Repo、repo_maxage: 3600、mirrors 后运行 fdroid update,从生成的 repo/index-v1.json 回读 repo 段:
repo/index-v1.json -> {'address': 'http://10.89.73.2:8149/c1/repo',
'name': 'Quzuo Demo Repo', 'maxage': 3600,
'mirrors': ['http://mirror1.example.internal/fdroid/repo']}
archive/index-v1.json -> {'address': 'http://10.89.73.2:8149/c1/archive',
'name': 'Quzuo Demo Repo Archive', 'maxage': 3600,
'mirrors': ['http://mirror1.example.internal/fdroid/archive']}
逐项说明:
- repo_url:仓库对外的完整地址,必须指向 repo 目录本身。索引里的
address字段即来自它。 - repo_name:仓库名称;归档仓库自动派生为「<repo_name> Archive」(实测
Quzuo Demo Repo Archive)。 - repo_maxage:索引有效期的秒数(实测 3600 → 索引
maxage: 3600),客户端按此判断何时强制刷新;不设则用默认值。 - repo_description / repo_icon / repo_web_base_url:仓库描述、图标路径(如
repo/icons/icon.png)、网页基址;repo_icon 指向不存在的文件时 update 会 WARNING 并生成占位图标(实测回显见安装篇)。 - make_current_version_link:为每个应用的当前版本建立
_<appid>_latest形式的固定链接,便于扫码或文档直链最新版。 - repo_pubkey:显式指定仓库公钥的路径(通常由签名密钥自动派生,无需设置)。
四、归档策略族:archive_older 的双向移动(重点实测)
归档族最核心的参数只有一个——archive_older:主仓库保留最近 N 个版本,更旧版本移入 archive/ 归档仓库(repo 的同级目录)。
实测配置 archive_older: 1,仓库中有 3 个 APK(fdroid_2000052、newpipe_998、newpipe_999),fdroid update -v:
DEBUG: Checking archiving for org.fdroid.fdroid - apks:3, keepversions:1, archapks:0
DEBUG: Checking archiving for org.schabi.newpipe - apks:3, keepversions:1, archapks:0
INFO: Moving org.schabi.newpipe_998.apk from repo to archive
⚠️ 注意:日志中的
apks:N是全仓库 APK 总数(全局列表计数),不是该应用的 APK 数——org.fdroid.fdroid 只有 1 个 APK 也显示 apks:3。读日志时不要被误导。
双向移动实证:把 org.schabi.newpipe 的元数据 CurrentVersionCode 改为 998(表示「当前版本」更旧)再跑 update:
DEBUG: Checking archiving for org.fdroid.fdroid - apks:2, keepversions:1, archapks:1
DEBUG: Checking archiving for org.schabi.newpipe - apks:2, keepversions:1, archapks:1
INFO: Moving org.schabi.newpipe_998.apk from archive to repo
INFO: Moving org.schabi.newpipe_999.apk from repo to archive
998 从 archive 搬回 repo,999 反向挪入 archive——archive_older 不是单向丢弃,而是随 CurrentVersionCode 动态平衡 repo 与 archive 两个目录,archive 仓库有自己的索引与地址(archive_url),旧版本依旧可下载。
keepversions 的三个加成规则(源码取证)
fdroidserver 实际保留的版本数 = keepversions,由 update.py 与 common.py(2.4.5 源码 2275-2320、4842-4853 行)计算,实测确认三条规则:
-
应用元数据可覆盖:在应用 yml 里写
ArchivePolicy: 3后实测日志变为org.fdroid.fdroid - keepversions:3,单应用覆盖全局 archive_older。 -
开发者签名文件加倍:若当前版本存在开发者签名文件(
fdroid signatures会把 APK 签名证书提取到metadata/<appid>/signatures/<vc>/),keepversions 自动翻倍。实测为 newpipe_998 生成签名文件后:Checking archiving for org.schabi.newpipe - apks:2, keepversions:2, archapks:1 Checking archiving for org.fdroid.fdroid - apks:2, keepversions:1, archapks:1(有签名文件的应用 keepversions=2,没有的仍为 1。)
-
构建配方的倍增仅在构建场景生效:默认保留版本数 = archive_older × len(VercodeOperation)(构建配方数),再以已启用的 builds 数封顶。注意 VercodeOperation 不能手写进应用元数据,实测报错:
CRITICAL: Unrecognised build flag 'VercodeOperation' in 'metadata/org.fdroid.fdroid.yml'
归档族其余参数
- archive_url:归档仓库独立地址(实测
http://10.89.73.2:8149/c1/archive),客户端可单独添加归档仓库; - archive_name / archive_icon / archive_description / archive_web_base_url:归档仓库的展示信息(默认名为「<repo_name> Archive」)。
五、密钥与签名族:信任锚的配置
| 参数 | 作用 | 实测情况 |
|---|---|---|
| keystore | 密钥库文件路径 | init 生成 keystore.p12(4294 B) |
| repo_keyalias | 仓库签名密钥别名 | init 默认 fdroid-server |
| keystorepass / keypass | 密钥库与密钥口令(无下划线) | init 自动生成随机口令写入 config |
| keydname | 密钥证书主题 | init 默认 CN=fdroid-server, OU=F-Droid |
| smartcardoptions | 硬件密钥(smartcard/HSM)参数 | 官方推荐生产场景外置密钥时使用 |
| gpgkey | GPG 签名身份(邮箱) | 实测启用后 gpgsign 生成 .asc |
| gpghome | GPG 家目录(默认 ~/.gnupg) | 机制说明 |
| repo_key_sha256 | 仓库签名密钥指纹 | 未设置时自动回填(见下) |
实测要点:
-
密钥指纹即信任锚:
keytool -list -keystore keystore.p12输出的 SHA-256 指纹(fdroid-server 别名)与 update 签名索引时打印的一致:INFO: Creating signed index with this key (SHA256): INFO: 10 D4 37 3F 83 1F 8B 67 BF EA 3F BF 4D C4 0E A0 EA EC 24 C1 F9 D4 7A E7 0C 34 BE 9D 60 C1 B9 6F -
gpgkey 联动 gpgsign:生成测试密钥(
gpg --batch --pinentry-mode loopback --passphrase "" --quick-generate-key "FDroid Demo <root@example.internal>" rsa2048 sign 0)并在 config.yml 设gpgkey: root@example.internal后,fdroid gpgsign实测输出:INFO: Signed org.schabi.newpipe_998.apk INFO: Signed org.schabi.newpipe_999.apk INFO: Signed entry.json INFO: Signed index-v1.json INFO: Signed index-v2.jsonrepo/ 目录随之出现
*.apk.asc分离签名,客户端(勾选「验证 PGP 签名」)可独立于索引 JAR 校验 APK。 -
repo_key_sha256 自动回填:配置中未显式设置该参数时,publish 流程会自动补齐——实测回显
WARNING: repo_key_sha256 not in config.yml, setting it to the signature key fingerprint of 'repo/signer-index.jar'。
⚠️ 生产安全:keystorepass/keypass 明文躺在 config.yml 里,务必收敛文件权限(
chmod 600 config.yml),并为 keystore.p12 做异地备份;官方更推荐 smartcard/HSM 或--keystore硬件方案托管生产密钥。
六、发布部署族:把仓库文件送到用户面前
fdroidserver 内建多种发布目标,fdroid deploy 一次执行、按配置分发:
| 参数 | 发布目标 | 说明 |
|---|---|---|
| serverwebroot | rsync/SSH 到 Web 服务器 | 可同时列多台;实测演示环境即此模式的同构操作(rsync 同步 repo/ 与 archive/ 到网页根) |
| identity_file | SSH 私钥路径 | 配合 serverwebroot 使用 |
| nonstandardwebroot | 非标准网页根声明 | 目标路径不符合常规布局时开启 |
| index_only | 只同步索引不同步 APK | 索引先行、APK 走旁路分发的进阶用法 |
| local_copy_dir | 本地目录副本(U 盘/离线介质) | 实测详见下 |
| servergitmirrors | git 镜像仓库 | 实测详见下 |
| github_releases / github_token | 发布到 GitHub Releases | 机制说明 |
| awsbucket / awssecretkey | 发布到 S3 | 机制说明 |
| rclone_config / path_to_custom_rclone_config / s3cmd | 发布到 rclone/S3cmd 支持的云存储 | 机制说明(数十种云存储) |
| sync_from_local_copy_dir | 从本地副本反向同步 | 离线签名机回灌场景 |
| deploy_process_logs | 保留 deploy 过程日志 | 机制说明 |
local_copy_dir 实测
路径必须以 fdroid 结尾,否则报错并给出修正建议(逐字回显):
ERROR: local_copy_dir does not end with "fdroid", perhaps you meant: "/srv/fdroid-copy/fdroid"
改为 /srv/fdroid-copy/fdroid 后执行 deploy,实测生成 repo/ 与 archive/ 两个子目录——复制的是完整仓库结构,可直接整盘带走离线分发。
servergitmirrors 实测与两个坑
- 单独设置
servergitmirrors: [<git 远端>]时,deploy 会把整个仓库镜像推送过去,实测对 bare 仓库执行后出现提交fdroidserver git-mirror(树中包含 fdroid/ 目录结构),日志INFO: Mirroring to: /srv/fdroid-mirror.git。 - 坑 1(本地路径):填本地路径虽然 deploy 能推,但后续
fdroid update生成索引时镜像 URL 解析会崩(IndexError: list index out of range,源码按 URL 分段解析 .git 地址)。servergitmirrors 必须填https://…/repo.git形式的 URL。 - 坑 2(离线机语义):servergitmirrors 与 local_copy_dir 同时设置时,deploy 判定为离线机,跳过 git 镜像生成(源码 deploy.py 明示 "Offline machine, skipping git mirror generation")——两个参数不要混用。
七、镜像与高可用族:mirrors
mirrors 是客户端侧故障切换的镜像清单:主站不可达时客户端自动尝试列表中的镜像。三条实测结论:
-
每个镜像基址必须以
fdroid结尾,否则 update 直接拒绝(逐字回显):ERROR: mirror '…' does not end with 'fdroid'! CRITICAL: Malformed repository mirrors. -
索引生成时自动按仓库段拼接:config 里填基址(如
http://mirror1.example.internal/fdroid),索引中生成…/fdroid/repo(主仓库)与…/fdroid/archive(归档仓库)两个地址(第三节索引回读已取证)。也支持 onion(Tor)地址作为镜像。 -
存放位置二选一:config.yml 的 mirrors 键,或独立文件
config/mirrors.yml;两处同时设置报mirrors set twice。
八、进阶参数族
per_app_repos(按应用分仓)
设为 true 后 deploy/update 会为每个应用生成独立子仓库,实测生成:
org.fdroid.fdroid/fdroid/repo/
org.schabi.newpipe/fdroid/repo/
(APK、.asc 签名、图标一并复制。)适合 nightly 构建等「每应用独立通道」的自动化发布。已知边界:2.4.5 对缺少 icon 字段的骨架元数据构建 per-app 索引时会崩(AttributeError: No such attribute: icon,源码 index.py 的 make_v0 逻辑判断 app.icon)——使用时先把元数据的图标信息补全。
install_list / uninstall_list(推送安装清单)
仓库运营者可在索引中标记设备应安装/卸载的应用(客户端侧需用户授权才会执行)。实测 install_list: [org.schabi.newpipe] 只反映在新格式索引 index-v2 的 repo.requests 字段:
{'install': ['org.schabi.newpipe'], 'uninstall': []}
(index-v1 无此字段——老客户端不感知该清单。)
binary_transparency_remote(二进制透明日志)
设置 git 远端后,每次 fdroid update 末尾实测出现:
INFO: Committing indexes to binary_transparency
本地 binary_transparency/ 目录形成 git 提交历史(add README + fdroid update,内容含 README.md、repo/、archive/ 与 filesystemlog.json),任何人可审计「哪个时间点发布过哪个索引」。注意:update 只做本地提交,推送到远端走 fdroid btlog --git-remote(deploy 流程会带上);fdroid btlog 默认拉取 https://f-droid.org 的公开日志,指向自建仓库时用 -u <仓库基址> --git-repo <本地 git 目录>(该目录需先 git init,否则报 CRITICAL: "…" does not exist!)。
质量扫描与元数据规范
- scan_binary / refresh_scanner / scanner_signature_sources:fdroid scanner 对 APK 的二进制扫描与可疑签名源(SUSS/exodus 等)配置;
- lint_licenses:fdroid lint 的许可白名单扩展(默认仅 SPDX 的 FSF/OSI 许可,实测非白名单许可报
Unexpected license tag "Unknown"!); - char_limits:各元数据字段的长度上限(描述 256、名称 50 等);
- current_version_name_source / release_notes_prepend:CurrentVersionName 取值来源与版本说明前缀,服务于自动化打包流水线。
构建环境族(fdroid build 场景)
sdk_path(SDK 路径)、ndk_paths(多版本 NDK 路径)、java_paths(多版本 JDK)、cachedir(构建缓存)、build_server_always(强制走 buildserver 虚拟机)、gradle/ant/mvn3(构建工具可执行文件名)。这一族只在源码构建流水线中生效,纯发布 APK 的仓库无需配置;init 写入的 sdk_path: /opt/android-sdk 对仓库管理命令无害(仅索引签名时调用其中 build-tools 的 apksigner)。
九、生产配置模板
以下模板由实测 config.yml 整理,占位值用尖括号标注,可直接落盘后修改:
# ===== 仓库身份(客户端可见) =====
repo_url: http://<对外IP或域名>:<端口>/fdroid/repo
repo_name: My Company Repo
repo_description: Internal Android application repository
repo_icon: repo/icons/icon.png
repo_maxage: 3600 # 索引有效期(秒)
make_current_version_link: true
# ===== 归档 =====
archive_older: 3 # 主仓库保留最近 3 个版本
archive_url: http://<对外IP或域名>:<端口>/fdroid/archive
# ===== 签名密钥(信任锚,chmod 600 保护) =====
keystore: keystore.p12
repo_keyalias: fdroid-server
keystorepass: <口令>
keypass: <口令>
keydname: CN=My Company, OU=F-Droid
# gpgkey: release@example.com # 可选:APK 分离 GPG 签名
# ===== 镜像高可用(基址必须以 fdroid 结尾) =====
mirrors:
- https://mirror2.example.internal/fdroid
- http://mirror3.example.internal/fdroid
# ===== 发布部署(按需启用,勿混用离线参数) =====
serverwebroot:
- user@web1.example.internal:/var/www/fdroid
identity_file: /root/.ssh/id_ed25519
# local_copy_dir: /srv/fdroid-copy/fdroid # 离线介质副本(离线机语义)
# servergitmirrors:
# - https://gitlab.example.internal/android/repo-mirror.git
# binary_transparency_remote: /srv/fdroid-btlog.git
配置生效方式:改完保存,重跑 fdroid update 重建索引即可让身份/镜像/归档类参数上线;部署类参数由 fdroid deploy 消费。
十、常见问题(实测取证)
Q1:mirror 报 does not end with 'fdroid'? 镜像基址必须以 fdroid 结尾(urljoin 会自动拼上 repo/archive 段),见第七节回显。
Q2:mirrors 写了两处报错?
config.yml 与 config/mirrors.yml 二选一,同时设置报 mirrors set twice。
Q3:local_copy_dir 生成的目录不对?
必须以 fdroid 结尾(如 /srv/fdroid-copy/fdroid),错误回显会给出建议路径。
Q4:手写 VercodeOperation 报 Unrecognised build flag? 它是构建服务内部配方,只能出现在构建配方的 build 段,不能写进应用元数据顶层(第四节实测)。
Q5:archive_older 把新版本也挪进 archive 了? 先检查应用元数据的 CurrentVersionCode——归档以「距当前版本的间隔」计算,CVC 设小了会把较新版本挪去 archive(第四节双向移动实证即此机制)。
Q6:per_app_repos 生成索引崩了?
2.4.5 已知边界:元数据缺 icon 字段时报 AttributeError: No such attribute: icon,先补全图标信息。
Q7:binary_transparency 只有本地提交,远端没更新?
update 只本地提交,推送走 fdroid btlog --git-remote 或 deploy 流程(第八节)。
十一、参考与延伸阅读
- 官方示例配置(参数全集权威清单):https://gitlab.com/fdroid/fdroidserver/-/raw/master/examples/config.yml
- 官方搭建指南《Setup an F-Droid App Repo》:https://f-droid.org/docs/Setup_an_F-Droid_App_Repo
- 签名流程文档《Signing_Process》:https://f-droid.org/docs/Signing_Process
- 本系列文档:
- 生态认知与选型:《F-Droid 介绍与选型指南》
- 安装与环境准备:《Ubuntu 22.04 安装 fdroidserver 2.4.5 指南》
- 命令族实测与备份恢复闭环:《fdroidserver 2.4.5 常用 CLI 命令与工具详解》