安装包靠网盘传、脚本路径各写各的、合作方永远装到旧 zip——多半不是文件坏了,而是没有统一的二进制入口:路径没约定、上传没认证、下载链接随手改。
下面用 AngusRepo 社区版私有化部署,按操作顺序走完一遍:安装 → 建 Raw HOSTED → 定路径 → curl 上传 / 下载 → 验证。主机写成 repo.example.com。需要匿名对外分发时,再把仓库标公开,见 内部包怎么公开给合作方。
1. 安装(得到可打开的控制台)
前提:Docker Engine + Compose v2;约 2 核 / 4 GB;放行 80;gm.example.com 与 repo.example.com 已解析。见 第一次跑通。
curl --fail --location --progress-bar -o AngusRepo-Community-1.0.0.zip \
https://repo.anguskit.com/raw/raw-public/AngusKit/repo/AngusRepo-Community-1.0.0.zip
unzip AngusRepo-Community-1.0.0.zip
cd AngusRepo-1.0.0
./install.sh
向导:Compose;Access 2;TLS 4(HTTP :80);Compose MySQL;Public DNS 如 example.com。然后:
./bin/angusctl.sh doctor # doctor: OK
打开 http://gm.example.com/ 与 http://repo.example.com/。HTTPS 见 安装与部署。下文默认 HTTP。
2. 建仓、令牌与路径约定
Raw 通常一个 HOSTED 即可,靠路径分层,不必为每个安装包建仓。
| 仓库名示例 | 类型 | 干什么 |
|---|---|---|
raw-hosted |
HOSTED | 托管任意文件:安装包、脚本、报告、二进制 |

推荐路径:项目/版本/文件名:
raw-hosted/
├── my-app/
│ ├── 1.0.0/
│ │ └── my-app-1.0.0-linux-amd64.tar.gz
│ └── 1.1.0/
│ └── my-app-1.1.0-linux-amd64.tar.gz
└── scripts/
└── deploy.sh
上传即覆盖:相同路径再次上传会直接盖掉旧文件,不保留历史。版本必须写进路径,不要只靠文件名「最新」。
准备:
- [ ] 访问令牌(只显示一次)
- [ ] CI 对
raw-hosted有 Write;下载账号有 Read(或仓库标公开后匿名读)
export REPO_USER="admin"
export REPO_TOKEN="your_access_token"
export REPO_HOST="repo.example.com"
字段说明见 Raw 格式。
3. 上传:curl --upload-file
# 准备一个示例文件
mkdir -p /tmp/angus-raw-demo && cd /tmp/angus-raw-demo
echo "hello-angus-raw" > README.txt
tar -czf my-app-1.0.0-linux-amd64.tar.gz README.txt
curl -u "$REPO_USER:$REPO_TOKEN" \
--upload-file ./my-app-1.0.0-linux-amd64.tar.gz \
"http://$REPO_HOST/raw/raw-hosted/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"
批量:
for file in dist/*.tar.gz; do
filename=$(basename "$file")
curl -u "$REPO_USER:$REPO_TOKEN" \
--upload-file "$file" \
"http://$REPO_HOST/raw/raw-hosted/my-app/1.0.0/${filename}"
done
写操作一律要认证,即使仓库已公开(公开只表示匿名可读)。
4. 下载:私有与公开
私有仓(推荐 Bearer):
curl -H "Authorization: Bearer $REPO_TOKEN" \
-O "http://$REPO_HOST/raw/raw-hosted/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"
或 Basic:curl -u "$REPO_USER:$REPO_TOKEN" -O "http://…"。
公开仓匿名:
curl -O "http://$REPO_HOST/raw/raw-hosted/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"
5. 验证闭环
# 上传后:控制台 Browse 应能看到路径 my-app/1.0.0/…
# 下载并核对内容
curl -u "$REPO_USER:$REPO_TOKEN" \
-o /tmp/got.tar.gz \
"http://$REPO_HOST/raw/raw-hosted/my-app/1.0.0/my-app-1.0.0-linux-amd64.tar.gz"
tar -tzf /tmp/got.tar.gz | head
应能列出 README.txt。可选:列出目录(API,以控制台/手册为准):
curl -u "$REPO_USER:$REPO_TOKEN" \
"http://$REPO_HOST/api/v1/repositories/raw-hosted/contents?path=/my-app/1.0.0/"
CI 最小片段
- run: |
curl -u "$REPO_USER:$REPO_TOKEN" \
--upload-file "./dist/my-app-${VERSION}-linux-amd64.tar.gz" \
"http://$REPO_HOST/raw/raw-hosted/my-app/${VERSION}/my-app-${VERSION}-linux-amd64.tar.gz"
6. 日常维护
- 路径里带版本;不要用
latest.tar.gz当唯一真相。 - 大文件注意反代超时与上传大小限制。
- 清理旧版本目录前先 Dry Run,见 清理策略。
- 对外分发:单独公开仓 +
/explore,勿把内网脚本仓整仓公开。
报错速查
| 症状 | 常见原因 | 怎么处理 |
|---|---|---|
| 401 Unauthorized | 令牌错误或未带认证上传 | -u user:token 或 Bearer |
| 404 Not Found | 路径拼错或未上传 | 对照 Browse 与 URL |
| 下载到旧内容 | 同路径被覆盖 | 版本写进路径,勿覆盖正式版 |
| 上传超时 | 反代 body/timeout 过小 | 调大限制后重试 |
FAQ
Raw 和 Maven/npm 有什么区别?
Raw 不做包格式解析,只按路径存文件。适合安装包、二进制、报告;有坐标体系的格式仍用对应 HOSTED。
为什么上传会覆盖?
Raw 无版本保护。要保留历史,路径必须含版本号(或哈希)。
能不能匿名上传?
不能。公开只放开读;写始终要登录/令牌。
小结
- 安装控制台 → 建
raw-hosted→ 约定项目/版本/文件名。 curl --upload-file上传;Bearer/Basic 或公开匿名下载。- 用最小 tar 包跑通上传 → Browse → 下载解压。