团队里往往同时有 Java、前端、Python、.NET、容器和系统包。与其为每种技术栈各维护一套私服,不如在同一套 AngusRepo 服务中管理这 28 种格式:Maven、Docker、npm、PyPI、NuGet、Helm、Go、APT、YUM、Raw、Alpine、Ansible、Arch、Cargo、Chef、CocoaPods、Composer、Conan、Conda、CRAN、Hugging Face、OCI、p2、Pub、RubyGems、Swift、Terraform、Vagrant。
每种格式都做三件事:完成认证、发布一个制品、再把它拉回来。密码字段填访问令牌。Hugging Face、CocoaPods 与 p2 按 PROXY 使用,协议只在 PROXY 上提供内容,写请求返回 405。CocoaPods 的创建页仍允许选 HOSTED,那种仓库没有 Pod 索引。Conan 1 不能建 GROUP。写操作落在 HOSTED。
先澄清一个常见误解:“一套制品库”指同一个 AngusRepo 服务,不是把所有格式上传到同一个仓库。要发布的格式创建HOSTED,例如
maven-releases、docker-releases。Hugging Face、CocoaPods 与 p2 创建PROXY。下文的仓库名和域名都是示例,应以仓库详情页的“接入配置”为准。
先花 3 分钟完成准备
如果你只使用一种技术栈,只阅读对应的小节即可。第一次接入建议按“发布 → 拉取”的顺序验证:能上传不代表客户端一定能正确下载。
1. 准备账号、令牌和仓库
登录控制台
打开 [AngusRepo 控制台]。自建实例请使用管理员提供的控制台地址。
新建令牌
在用户设置 → 我的令牌新建令牌,例如
local-macbook。令牌只显示一次,请立即保存;遗失后需吊销并重新创建。新建 HOSTED 仓库
在仓库中新建对应格式的HOSTED仓库,并确认账号拥有上传权限。
复制接入配置
打开仓库的接入配置,以页面给出的仓库名、地址、发行版和组件为准。
在接下来的命令中,登录名和令牌分别放入环境变量。export仅在当前终端有效,因此请在同一个终端继续执行后续命令。
exportREPO_USER="your-username"exportREPO_TOKEN="your_access_token"REPO_USER是登录名,不是令牌名称。对 Maven、Docker、npm、NuGet 等协议,令牌作为密码传入;文中出现的--password、--api-key和_authToken都应填REPO_TOKEN,而不是登录密码。
**安全提示:**将令牌写入 URL 会出现在终端历史或本机配置中。仅在受控环境使用示例命令;共享机器或 CI 请改用密钥管理能力,并在验证后清理临时配置。
2. 地址速查
| 格式 | 拉取地址或标识 | 发布方式 |
|---|---|---|
| Maven | https://主机/maven/<仓库名>/ | 同一地址,mvn deploy |
| Docker | 主机/<仓库名>/<镜像>:<标签> | 同一镜像名,docker push |
| npm | https://主机/npm/<仓库名>/ | npm publish |
| PyPI | /pypi/<仓库名>/simple/ | /pypi/<仓库名>/legacy/ |
| NuGet | /nuget/<仓库名>/v3/index.json | 同一源,--api-key使用令牌 |
| Helm | /helm/<仓库名>/或oci://主机/helm/<仓库名> | HTTP 上传或helm push |
| Go | /go/<仓库名>/,配置GOPROXY | 控制台或管理 API |
| APT | /apt/<仓库名>/ | 上传到pool/<文件名> |
| YUM | /yum/<仓库名>/ | POST .../upload |
| Raw | /raw/<仓库名>/<路径> | 同一路径,curl -T |
| Alpine | /alpine/<仓库名>/<分支>/<组件>/ | curl -T上传.apk |
| Ansible | /ansible/<仓库名>/api/v3/ | ansible-galaxy collection publish |
| Arch | /arch/<仓库名>/os/$arch | curl -T上传.pkg.tar.zst |
| Cargo | sparse+https://主机/cargo/<仓库名>/ | cargo publish |
| Chef | /chef/<仓库名> | POST .../api/v1/cookbooks |
| CocoaPods | /cocoapods/<仓库名> | 按 PROXY 使用,pod install |
| Composer | /composer/<仓库名> | POST .../api/packages |
| Conan | /conan/<仓库名> | conan upload |
| Conda | /conda/<仓库名> | curl -T,conda install -c |
| CRAN | /cran/<仓库名> | 上传src/contrib/*.tar.gz |
| Hugging Face | /huggingface/<仓库名> | 按 PROXY 使用,HF_ENDPOINT |
| OCI | /v2/<仓库名>/ | oras push |
| p2 | /p2/<仓库名> | 按 PROXY 使用,Eclipse / Tycho |
| Pub | /pub/<仓库名>/ | dart pub publish |
| RubyGems | /rubygems/<仓库名> | gem push |
| Swift | /swift/<仓库名> | swift package-registry publish |
| Terraform | /terraform/<仓库名> | 上传 module / provider zip |
| Vagrant | /vagrant/<仓库名>/<user>/<box> | 上传.box,vagrant box add |
下文统一使用repo.anguskit.com作为主机名。自建实例请整体替换为你的实际地址。
Maven
在包含pom.xml的工程根目录执行。settings.xml和pom.xml中的仓库id必须完全一致。
认证
将以下内容保存为工程根目录的settings.xml。如果已存在~/.m2/settings.xml,只需把<server>合并进去;不要覆盖原文件。
<settings><servers><server><id>angusrepo-maven-releases</id><username>${env.REPO_USER}</username><password>${env.REPO_TOKEN}</password></server></servers></settings>发布
在pom.xml增加发布地址,随后执行部署。成功日志会显示BUILD SUCCESS。
<distributionManagement><repository><id>angusrepo-maven-releases</id><url>https://repo.anguskit.com/maven/maven-releases</url></repository></distributionManagement>mvn-ssettings.xml clean deploy验证拉取
在另一个工程加入同一仓库,然后用刚发布的groupId、artifactId和version验证。
<repositories><repository><id>angusrepo-maven-releases</id><url>https://repo.anguskit.com/maven/maven-releases</url></repository></repositories>mvn-ssettings.xml dependency:get\-Dartifact=你的groupId:你的artifactId:你的versionDocker
在包含Dockerfile的目录执行。镜像名采用主机/仓库名/镜像:标签格式;不要手动加入/v2。
认证
echo"$REPO_TOKEN"|dockerlogin repo.anguskit.com\-u"$REPO_USER"--password-stdin看到Login Succeeded后继续。
发布
dockerbuild-tmyapp:1.0.0.dockertag myapp:1.0.0 repo.anguskit.com/docker-releases/myapp:1.0.0dockerpush repo.anguskit.com/docker-releases/myapp:1.0.0验证拉取
dockerpull repo.anguskit.com/docker-releases/myapp:1.0.0npm
在包含package.json的目录执行。源地址末尾的/不能省略,.npmrc中的${NPM_TOKEN}应保持原样。
认证
在项目根目录创建或补充.npmrc:
registry=https://repo.anguskit.com/npm/npm-releases/ //repo.anguskit.com/npm/npm-releases/:_authToken=${NPM_TOKEN} always-auth=true然后在同一终端执行:
exportNPM_TOKEN="$REPO_TOKEN"发布
package.json中的name和version就是待发布的包信息。若该版本已存在,请先提高version。
npmpublish验证拉取
npminstallyour-package如果发布的是@scope包,还要在.npmrc增加:
@scope:registry=https://repo.anguskit.com/npm/npm-releases/PyPI
在包含pyproject.toml的目录执行。上传使用/legacy/,安装使用/simple/;包名以pyproject.toml的name为准。
准备环境
python3-mvenv .venvsource.venv/bin/activate python3-mpipinstallbuild twine发布
dist/由构建命令生成,无需手动创建。
python3-mbuild twine upload\--repository-url https://repo.anguskit.com/pypi/pypi-releases/legacy/\-u"$REPO_USER"-p"$REPO_TOKEN"dist/*验证拉取
pipinstallyour-package\--index-url"https://${REPO_USER}:${REPO_TOKEN}@repo.anguskit.com/pypi/pypi-releases/simple/"NuGet
在包含.csproj的目录执行。NuGet 源地址必须以/v3/index.json结尾。
认证
该命令会将凭据保存到本机 NuGet 配置中。
dotnet nugetaddsourcehttps://repo.anguskit.com/nuget/nuget-releases/v3/index.json\--nameangusrepo\--username"$REPO_USER"\--password"$REPO_TOKEN"\--store-rest-token发布
dotnet pack-cRelease dotnet nuget push bin/Release/Your.Package.1.0.0.nupkg\--sourcehttps://repo.anguskit.com/nuget/nuget-releases/v3/index.json\--api-key"$REPO_TOKEN"其中.nupkg文件名请以dotnet pack的实际输出为准。
验证拉取
在另一个已有工程中执行:
dotnetaddpackage Your.Package--version1.0.0--sourceangusrepo dotnet restoreHelm
Helm 支持 HTTP 和 OCI 两种协议。请根据仓库“接入配置”选择其中一种:显示helm repo add就走 HTTP;显示oci://就走 OCI。不要混用两套命令。当前目录应包含带有Chart.yaml的 Chart。
HTTP 协议
helm repoaddangusrepo https://repo.anguskit.com/helm/helm-releases\--username"$REPO_USER"--password"$REPO_TOKEN"helm package ./mychartcurl-u"$REPO_USER:$REPO_TOKEN"\-F"chart=@mychart-1.0.0.tgz"\"https://repo.anguskit.com/helm/helm-releases/api/charts"helm repo update helminstallmy-release angusrepo/mychartmychart-1.0.0.tgz应替换为helm package的实际输出文件名。
OCI 协议
echo"$REPO_TOKEN"|helm registry login repo.anguskit.com\-u"$REPO_USER"--password-stdin helm package ./mychart helm push mychart-1.0.0.tgz oci://repo.anguskit.com/helm/helm-releases helminstallmy-release oci://repo.anguskit.com/helm/helm-releases/mychart--version1.0.0Go
go get只负责拉取模块。上传请使用控制台或管理 API,不要把请求发送到repo.anguskit.com/api。模块路径来自go.mod,版本必须以v开头,例如v1.0.0。
配置拉取
私有模块需配置GOPROXY和模块域名。GONOSUMDB请替换为你的模块域名,否则校验可能失败。
exportGOPROXY="https://${REPO_USER}:${REPO_TOKEN}@repo.anguskit.com/go/go-releases"exportGONOSUMDB=example.com发布
在模块根目录执行。生成的 ZIP 顶层目录必须是模块路径@版本/,且其中必须包含go.mod。云上实例使用以下 API 地址;自建实例请向管理员确认管理 API 基址。
exportAPI_BASE="https://bj-c1-prod-apis.anguskit.com/repo"exportMODULE="$(go list-m)"exportVERSION="v1.0.0"exportPREFIX="${MODULE}@${VERSION}"STAGE="$(mktemp-d)"mkdir-p"${STAGE}/${PREFIX}"cpgo.mod *.go"${STAGE}/${PREFIX}/"(cd"${STAGE}"&&zip-qr"${OLDPWD}/module-${VERSION}.zip""${PREFIX}")rm-rf"${STAGE}"curl-u"$REPO_USER:$REPO_TOKEN"\-F"repositoryName=go-releases"\-F"version=${VERSION}"\-F"modulePath=${MODULE}"\-F"zip=@./module-${VERSION}.zip"\"$API_BASE/api/v1/go/upload"也可以在该 Go 仓库的上传页选择生成的 ZIP 文件。
验证拉取
go get example.com/go-demo@v1.0.0APT
准备一个已经构建好的.deb包。安装时使用包内的软件包名,而不是.deb文件名。stable和main必须与仓库的发行版、组件一致;如接入配置显示不同值,请以页面为准。
发布
curl-u"$REPO_USER:$REPO_TOKEN"-T./my-package_1.0.0_amd64.deb\"https://repo.anguskit.com/apt/apt-releases/pool/my-package_1.0.0_amd64.deb"验证拉取
上传后索引生成可能需要几秒钟。将my-package换为包内软件包名:
echo"deb [trusted=yes] https://${REPO_USER}:${REPO_TOKEN}@repo.anguskit.com/apt/apt-releases stable main"\|sudotee/etc/apt/sources.list.d/angusrepo.listsudoapt-getupdate&&sudoapt-getinstallmy-packageYUM
准备一个已经构建好的.rpm包。安装名使用 RPM 包名,而不是文件名。
发布
上传必须使用表单字段file:
curl-u"$REPO_USER:$REPO_TOKEN"\-F"file=@./my-package-1.0.0-1.noarch.rpm"\"https://repo.anguskit.com/yum/yum-releases/upload"验证拉取
以下命令会写入/etc/yum.repos.d/angusrepo.repo。刚上传完成时若找不到包,稍等后重试。
sudotee/etc/yum.repos.d/angusrepo.repo>/dev/null<<EOF [angusrepo] name=AngusRepo YUM baseurl=https://${REPO_USER}:${REPO_TOKEN}@repo.anguskit.com/yum/yum-releases/ enabled=1 gpgcheck=0 EOFsudodnf clean all&&sudodnfinstallmy-packageRaw
Raw 仓库适合保存不属于特定包管理格式的文件。自行约定清晰的路径,例如项目/版本/文件名;上传和下载必须使用同一条 URL。
发布
curl-u"$REPO_USER:$REPO_TOKEN"-T./my-app-1.0.0-linux-amd64.tar.gz\"https://repo.anguskit.com/raw/raw-releases/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"同一路径再次上传会覆盖现有文件。
验证拉取
换一个目录下载,避免与本地源文件重名:
mkdir-p/tmp/raw-check&&cd/tmp/raw-checkcurl-u"$REPO_USER:$REPO_TOKEN"-O\"https://repo.anguskit.com/raw/raw-releases/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"常见问题排查
| 现象 | 优先检查 |
|---|---|
| 发布返回 403 | 令牌所属账号是否拥有目标仓库写权限。 |
| Docker 推送失败 | 镜像名不应包含/v2;本地必须先成功docker build。 |
| npm 返回 401 或 404 | 源地址和_authToken路径是否一致,且 URL 末尾是否保留/;确认已设置NPM_TOKEN。 |
| PyPI 上传或安装失败 | 上传地址应为/legacy/,安装地址应为/simple/;先执行python3 -m build。 |
| NuGet 还原失败 | 源地址是否以/v3/index.json结尾,以及本机是否已保存正确凭据。 |
| Helm 返回 401 | HTTP 与 OCI 流程不可混用;OCI 推送前必须执行helm registry login。 |
| APT 或 YUM 找不到刚上传的包 | 等待索引刷新后再次更新缓存;同时确认使用的是包内名称。 |
| Go 上传失败 | ZIP 顶层目录必须为模块路径@版本/,上传地址必须是管理 API。 |
认证方式说明
协议路径(例如/maven/、/npm/、/v2/)使用 Basic Auth:用户名为登录名,密码为访问令牌。管理 REST API 按接口说明使用 Bearer Token。遇到认证问题时,先确认没有把这两种方式混用。
原文地址:anguskit.com