安装与 service 注册¶
选择部署方式¶
方式 |
适合 |
起手步骤 |
|---|---|---|
预编译 binary + systemd |
长期生产、单机 / 多边缘、目标机无需构建工具链 |
下载同 tag 安装脚本、审阅、安装,再单独注册服务 |
|
已有 Go 工具链、希望本机编译 |
安装明确版本;首次启动自动取得同版本 UI |
docker compose |
容器部署(PostgreSQL / 对象存储保持外部) |
服务端业务配置统一为 YAML。不同部署方式可使用同一配置模型,但迁移时仍须核对路径、属主、数据库版本及一致性备份;不能同时用两个实例写同一 pb_data。
新分发格式的适用范围
下文 TAG=vX.Y.Z 是必须替换的占位符:请选择已经采用新流程、且所需附件已经公开的服务端 tag。这套流程变更本身不是一次新发行,历史 v0.34.0 不会补发这些新格式产物;不要重发旧 tag,也不要用 latest 掩盖发布切换窗口。
安装预编译 binary(推荐)¶
新流程使用 GoReleaser v2.18.1 的默认归档命名,支持 linux/amd64、linux/arm64、darwin/arm64 三个平台:
qatlasd_<version>_linux_amd64.tar.gz
qatlasd_<version>_linux_arm64.tar.gz
qatlasd_<version>_darwin_arm64.tar.gz
qatlasd_<version>_web.zip
qatlasd_<version>_checksums.txt
<version> 不带前导 v。每个 tar.gz 内是普通文件 qatlasd(另有默认收录的说明 / 许可证),不是旧式裸附件 qatlasd-<os>-<arch>。官方预编译程序已内嵌完整 UI 与文档,首次启动不需要联网下载 UI;业务功能依赖的数据库、外部 API 等网络需求不变。
从同一新 tag 下载脚本,审阅后执行¶
# 必须替换为已采用新流程且附件已公开的 tag
TAG=vX.Y.Z
curl -fL --proto '=https' --proto-redir '=https' \
"https://raw.githubusercontent.com/IAI-USTC-Quantum/QuantumAtlas/$TAG/cmd/qatlasd/install-qatlasd.sh" \
-o install-qatlasd.sh
less install-qatlasd.sh
# 审阅通过后再执行;脚本版本与安装目标必须相同
sh install-qatlasd.sh --version "$TAG"
# 如需更换安装目录,在上述执行命令中另加:--dir /opt/qatlas/bin
默认安装位置为 ~/.local/bin/qatlasd。确认该目录在 PATH 中;指定其他目录时,调用者须自行保证写权限。脚本保留 QATLAS_VERSION、QATLAS_INSTALL_DIR、QATLAS_REPO 工具覆盖项,它们不是服务端业务配置;生产建议显式传 --version 和 --dir。
安装器需要 curl(优先)或 GNU wget、tar、sha256sum 或 shasum,以及标准命令行工具(如 awk、cmp、mktemp)。BusyBox wget 缺少所需的禁止自动重定向能力,会明确被拒绝;这种环境请安装 curl。脚本是 POSIX sh,但不意味着任意极简 BusyBox 环境都已具备这些工具。
QATLAS_INSTALL_TIMEOUT 默认 60 秒,用于每次请求 / 归档处理步骤;QATLAS_INSTALL_VERSION_TIMEOUT 默认 10 秒,用于候选 binary 的版本执行检查。两者都只接受 1..300 的秒数,不是总升级时限。按需仅给该次安装调用设置,例如:
QATLAS_INSTALL_TIMEOUT=120 QATLAS_INSTALL_VERSION_TIMEOUT=20 \
sh install-qatlasd.sh --version "$TAG"
这些是安装工具参数,不要把它们写入业务 YAML 或用来配置服务环境。下载脚本失败时停止,不要执行磁盘上的残留旧脚本。
首次迁移不能使用旧服务内嵌的安装脚本
/install-qatlasd.sh 由正在运行的 qatlasd 内嵌提供。旧实例仍返回只认识旧附件格式的脚本,不能用它安装新格式。首次升级必须使用上面同一新 tag 的 raw.githubusercontent.com 脚本入口;首次升级完成后,实例提供的内嵌脚本才随新 binary 切换。本流程不提供旧格式兼容层。
脚本的安全替换边界¶
检测支持的 OS / arch,解析目标 tag,下载对应
tar.gz和qatlasd_<version>_checksums.txt。校验归档 SHA256;缺失、重复或不匹配的校验记录会失败。
严格检查 tar 成员,拒绝危险路径、链接、重复条目等;只取预期的唯一普通
qatlasd,不把整个归档直接解到安装目录。在目标文件系统内创建临时文件、设置执行权限,并执行
--version,精确核对目标版本。全部通过后才 atomic rename 替换目标。下载、校验、解包、版本检查或替换失败,不改旧 binary /
config.yaml。
脚本不会自动 sudo、生成 / 覆盖配置、注册服务或重启服务。替换 binary 与注册服务是两件独立的事;后者会启动服务,须在配置和数据准备好后单独执行。
Release 资产的校验方式¶
SHA256 校验是安装器的必经步骤,用于发现传输、落盘或镜像内容不一致。同源 checksum 不是签名:能同时替换归档与校验清单的攻击者可以让二者重新匹配。HTTPS 和 checksum 也不代表源码本身安全。
手动核验时,下载同 tag 清单并找到目标归档的唯一一条记录,再比对本地摘要:
TAG=vX.Y.Z # 替换为符合上述条件的公开 tag
VERSION=${TAG#v}
ARTIFACT="qatlasd_${VERSION}_linux_amd64.tar.gz" # 按实际平台修改
BASE="https://github.com/IAI-USTC-Quantum/QuantumAtlas/releases/download/$TAG"
curl -fL "$BASE/$ARTIFACT" -o "$ARTIFACT"
curl -fL "$BASE/qatlasd_${VERSION}_checksums.txt" -o "qatlasd_${VERSION}_checksums.txt"
sha256sum "$ARTIFACT" # macOS 可用 shasum -a 256 "$ARTIFACT"
后续采用新 workflow 的版本会在 GoReleaser 发布后,由官方 actions/attest 生成签名构建证明并默认登记到 GitHub;归档与 UI ZIP 仍取自默认版本化 qatlasd_<version>_checksums.txt 清单。已发布的 v0.35.0-rc.1 不追溯补签,不能视作已有这套新 GitHub 证明。选用新 workflow 的产物时,确认对应 attestation 步骤成功,再用 GitHub CLI 验证:
gh attestation verify "./$ARTIFACT" --repo IAI-USTC-Quantum/QuantumAtlas
# 对已下载的 UI zip,验证对象同样是 zip 本身:
gh attestation verify "./qatlasd_${VERSION}_web.zip" --repo IAI-USTC-Quantum/QuantumAtlas
证明对象是 tar.gz / zip 归档本身,不是解出的 qatlasd。 检查验证结果里的仓库、workflow、tag / commit 是否符合预期。Provenance 证明特定构建身份与产物摘要的关联,不保证源码 / 依赖安全或程序无 bug。安装器和运行时 UI 下载器不会自动执行这一步 attestation 核验。新 Release 先 draft、附件全部上传成功后自动公开,再生成证明;若证明步骤失败,Release 可能已公开,维护者须先核对实际状态,不直接重跑覆盖。
用 Go 原生安装¶
Git / Go 模块只分发源码,不提交生成的 web/dist。安装明确的公开版本只需要符合仓库 go.mod 要求的 Go 工具链,不需要 Node、npm 或 Sphinx:
# vX.Y.Z 必须替换为已采用新流程、带公开 UI 资源的 tag
go install github.com/IAI-USTC-Quantum/QuantumAtlas/cmd/qatlasd@vX.Y.Z
# 默认在 ~/go/bin;若设置了 GOBIN / GOPATH,以实际位置为准
~/go/bin/qatlasd --version
版本优先取有效的 main.version 注入值,其次取 Go build info 的 Main.Version;CLI / API 展示统一去掉前导 v(例如输出 qatlasd version X.Y.Z)。--version 不需要业务配置、数据库或 UI 下载。
首次启动与按版本离线缓存¶
普通 go install 不嵌入生成资源。首次 serve 在没有内嵌资源时,从程序的精确版本下载:
https://github.com/IAI-USTC-Quantum/QuantumAtlas/releases/download/v<version>/qatlasd_<version>_web.zip
https://github.com/IAI-USTC-Quantum/QuantumAtlas/releases/download/v<version>/qatlasd_<version>_checksums.txt
下载器核对 SHA256 + zip comment 中的版本,并验证资源结构后,缓存到:
os.UserCacheDir()/qatlas/ui/v<version>/
├── bundle.zip
└── sha256
后续启动按版本重新验证本地缓存,可离线提供 UI;升级到新版本使用新的版本目录,不复用旧版本资源。Linux 通常为 ${XDG_CACHE_HOME:-$HOME/.cache}/qatlas/ui/,macOS 通常为 ~/Library/Caches/qatlas/ui/。以实际服务运行用户的缓存目录为准,不能用 root 的缓存代替普通服务用户的缓存。
zip 与官方二进制内嵌资源来自同一次 Sphinx 两站构建 + npm 构建产物,通过统一 fs.FS 提供 SPA、静态文件与文档路由。资源下载和选择不新增业务 YAML 字段;现有部署仍按 config init 配置 PostgreSQL / OAuth / S3 等即可。
dev、(devel) 或 Go pseudo-version 不能据此下载一个“差不多的 latest”:没有有效发布版本、附件尚为 draft / 不存在、校验失败都会明确报错,不会回退 latest。请选择带公开资源的新 tag;开发者则按贡献指南完成 Sphinx 两站及 npm 全 UI 构建,再用 go build -tags embedui ./cmd/qatlasd 编译内嵌版本。仅加 build tag 不会代替资源构建。
常见错误¶
404 / 缺少资源:核对 tag 是否采用新流程、Release 和对应平台归档 / UI zip / checksum 是否已公开。Git tag 可被
go install发现,不代表 Release 附件已经可下载。缓存损坏 / 不完整:启动会拒绝使用,不能跳过校验。确认服务用户和版本后,移走该版本缓存目录,再在可联网时重新启动;不要手改
sha256让损坏资源通过。目录不可写:安装目录和运行用户的缓存目录是两种权限。检查失败发生在哪一步,按需修正目录属主 / 服务沙箱;不要让安装器自动提权。
不支持的平台:官方仅发上述三平台;其他平台可尝试明确版本的 Go 源码安装,不等于承诺经过生产验证。
准备 YAML 配置¶
# 默认 ~/.qatlas/config.yaml;已有文件时拒绝覆盖
qatlasd config init
# 或指定路径(调用者须有写权限)
qatlasd config init --config /path/to/config.yaml
# 编辑后检查路径与有效配置(secret 默认脱敏)
qatlasd config path --config /path/to/config.yaml
qatlasd config show --config /path/to/config.yaml
新建模板为 mode 0600,按需取消注释并填写。完整字段见随 binary 提供的模板和服务端配置;不要在升级时对已有配置运行 config init --force。
服务端不读取 .env 或 process env 作为业务配置;残留的 QATLAS_* 业务变量、MINERU_*、GITHUB_CLIENT_* 等旧配置变量会触发报错,须迁入 YAML 并从服务环境删除。安装工具覆盖项例外,不应用来配置业务。
配置文件必须能被最终服务用户读取。若用 sudo qatlasd config init --config /etc/quantum-atlas/config.yaml 创建,文件由 root 拥有且为 0600;注册成普通用户运行的 system service 前,须明确调整属主 / 访问权限,不能只因文件存在就认为服务能读。
注册为系统服务¶
qatlasd service install 使用当前执行的 binary 路径生成服务,显式传入 YAML 路径最易审计:
# 先在前台检查;确认后 Ctrl-C,再注册服务
qatlasd --config "$HOME/.qatlas/config.yaml" serve --http=127.0.0.1:4200
# user mode,不用 sudo;非 TTY 必须同时给 --mode 和 --force
qatlasd service install --mode user \
--config "$HOME/.qatlas/config.yaml" --bind 127.0.0.1:4200 --force
# system mode:从预定服务用户的 shell 运行 sudo
sudo /home/<USER>/.local/bin/qatlasd service install --mode system \
--config /etc/quantum-atlas/config.yaml --bind 127.0.0.1:4200 --force
交互模式会提示 user / system、确认默认 ~/.qatlas/config.yaml(若存在)、渲染 unit 并确认写入。显式 --config 必须指向已存在的文件;未指定且默认文件不存在时,unit 不固定 --config,运行时按服务用户的默认路径加载。注册会写入并启动服务,不是仅生成模板。
Flag |
默认 |
含义 |
|---|---|---|
|
TTY 询问;非 TTY 必填 |
服务安装位置与管理模式 |
|
已存在的 |
写入 |
|
|
写入 |
|
|
服务名 |
|
false |
只渲染,不写盘、不 reload;非 TTY 仍须 |
|
false |
跳过确认并允许替换已有 unit;非 TTY 必填 |
不要混用 sudo 与 user mode
system mode 写 /etc/systemd/system/,需要 root 写权限,但运行用户优先由 $SUDO_USER 决定,并非默认必须 root 运行。应从预定运行用户的 shell 调用 sudo qatlasd service install --mode system ...;不要用 sudo -u <user> ... --mode system,也不要用 sudo ... --mode user。若 sudo 的 PATH 找不到 binary,使用绝对路径。
systemd unit 示例¶
以下是 system mode 的语义示例;实际结果以 service install --dry-run --mode system --config ... --force 为准:
[Unit]
Description=QuantumAtlas server (Go + PocketBase)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=<USER>
WorkingDirectory=/etc/quantum-atlas
ExecStart=/home/<USER>/.local/bin/qatlasd --config /etc/quantum-atlas/config.yaml serve --http=127.0.0.1:4200
Restart=on-failure
RestartSec=5
KillSignal=SIGINT
TimeoutStopSec=15
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=no
ReadWritePaths=/etc/quantum-atlas /home/<USER>/.local/share/qatlasd
LockPersonality=true
RestrictRealtime=true
[Install]
WantedBy=multi-user.target
自动生成的 ReadWritePaths 包含配置目录、默认 XDG 数据目录和已存在的 ~/QuantumAtlas-Wiki,不会解析 YAML 中的自定义存储路径。非默认数据路径或额外只读沙箱需要管理员核对 drop-in;无内嵌 UI 时也须确保运行用户的缓存目录可写。ProtectSystem=full 本身不把整个 home 设为只读。
ReadWritePaths 与启动权限
列出的目录不存在可能导致 status=226/NAMESPACE。在注册 / 重启前创建目录、核对属主与权限;修改 unit / drop-in 后要 daemon-reload,只改 YAML 则重启即可。不要以旧进程仍正常运行为依据跳过下一次启动验证。
验证与管理¶
# user mode
qatlasd service status --mode user
journalctl --user -u qatlasd -n 50
# system mode(不要让普通用户命令默认检查 user unit)
sudo qatlasd service status --mode system
journalctl -u qatlasd -n 50
curl http://127.0.0.1:4200/api/health | jq
healthy / degraded 应结合 checks 和日志判断;还应检查首页、JS 与文档能否加载。user unit 若要未登录也常驻,需按本机权限配置 loginctl enable-linger。macOS 的 launchd 服务管理仍须单独验证,不能将 Linux 的 systemd 验证等同于 macOS 生产验证。
升级与卸载¶
升级必须先读目标版本说明并备份,再安全替换,最后显式重启 / 验证。不要将“保留旧 binary”当作“可回滚数据库”的保证;完整步骤见备份与升级。
卸载时显式选择正确模式:
qatlasd service uninstall --mode user
# system mode 则用:sudo qatlasd service uninstall --mode system
trash-put ~/.local/bin/qatlasd
# config.yaml、pb_data、raw 和 UI 缓存不会自动删除,另行决定保留策略
不使用 service 时,直接前台运行 qatlasd --config /path/to/config.yaml serve --http=127.0.0.1:4200,由容器或其他进程管理器托管即可。