一直想弄个自己的类 S3 文件存储,最近 RustFS 正式版上线,pigsty 创始人维护的 MinIO 分支 Silo 也正式发布了文档,正好我搞链上小草项目时买了好几个电视盒子闲置,配置是 CM311-1a(S905L3a,2GB RAM,16GB eMMC),干脆拿一个来试试。七牛的免费空间只有 10G,折腾一下我又可以多10G存储空间了。对比之后选了 Silo,装好使用下来非常顺滑。
为什么选 Silo
选型时在 RustFS 和 Silo 之间纠结了一下:
| 对比项 | Silo | RustFS |
|---|---|---|
| 文件系统要求 | 任意目录即可,非强制 XFS | 强烈推荐 XFS,要求独立分区 |
| 单盘部署 | 支持,灵活 | 支持,但要求专用磁盘 |
| Docker 部署 | 镜像成熟,多架构支持 | 可用 |
我的盒子是 eMMC 存储,再分区太折腾了,Silo 随便指个空目录就能跑。另外 Silo 是 MinIO 的分支,S3 接口兼容,mc、各语言 SDK 这些客户端拿来就能用,生态这块不用操心。
部署方式选了 Docker:就一个服务,管理简单;2GB 内存下 Docker 额外开销(约 110MB)完全可以接受;后面升级、回滚也方便。
环境准备
- 硬件:CM311-1a(S905L3a,2GB RAM,16GB eMMC)
- 系统:Armbian 6.1.96-ophub
- 网络:公网服务器 + FRP + Caddy 反向代理
先看看 eMMC 的健康状态,顺便确认一下架构和内存:
sudo apt install mmc-utils -y
sudo mmc extcsd read /dev/mmcblk0 | grep -E "DEVICE_LIFE_TIME|PRE_EOL_INFO"
uname -m # 应为 aarch64
free -hPRE_EOL_INFO 是 0x01 就说明磨损还正常,我这台显示寿命消耗才 0-10%,放心折腾。
时区和时间同步也顺手设置一下,对象存储对时间比较敏感:
sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-ntp true
timedatectl确认 System clock synchronized: yes、NTP service: active 就 OK。
安装 Docker
curl -fsSL https://get.docker.com | sudo sh
sudo systemctl enable --now dockereMMC 经不起无限制的日志写入,顺手把 Docker 日志轮转配上:
sudo tee /etc/docker/daemon.json <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
sudo systemctl restart docker部署 Silo
拉取镜像,版本号到 Silo Releases 取最新的:
docker pull pgsty/silo:RELEASE.2026-09-16T00-00-00Z创建数据目录,Silo 任意空目录都能用:
mkdir -p ~/silo/data
sudo chown -R 1001:1001 ~/silo/data # 容器以非 root 用户运行,需要设置权限启动容器:
docker run -d --name silo --restart unless-stopped \
-p 9000:9000 \
-p 9001:9001 \
-v ~/silo/data:/data \
-e "MINIO_UPDATE=off" \
-e "MINIO_ROOT_USER=你的用户名" \
-e "MINIO_ROOT_PASSWORD=你的强密码" \
docker.io/pgsty/silo:RELEASE.2026-09-16T00-00-00Z \
server /data --console-address ":9001"几个关键参数:
| 参数 | 作用 |
|---|---|
--restart unless-stopped | 开机自启 |
-p 9000:9000 | S3 API 端口 |
-p 9001:9001 | Web 控制台端口 |
-v ~/silo/data:/data | 数据持久化 |
MINIO_ROOT_PASSWORD | 至少 8 字符,否则启动失败 |
验证一下:
docker ps
docker logs silo
docker stats silo --no-stream
free -h正常日志长这样:
Silo Object Storage Server
Version: RELEASE.2026-09-16T00-00-00Z (go1.27.1 linux/arm64)
API: http://127.0.0.1:9000
WebUI: http://127.0.0.1:9001实测内存占用约 136MB,2GB 的盒子跑起来毫无压力。
FRP + Caddy 对外暴露
盒子在内网,走 FRP 转发到公网服务器,再用 Caddy 套上 HTTPS。
内网盒子的 frpc.toml 里新增:
[[proxies]]
name = "silo-s3"
type = "http"
localPort = 9000
subdomain = "s3" # 最终访问 s3.xxx.com
subdomainHost = "xxx.com"已在 frps 中配置,frpc 这边只需指定子域名前缀。
公网服务器的 Caddyfile 里,给 S3 单独写一个站点块,不要复用通配符块:
s3.xxx.com {
# 强制 HTTPS
@http protocol http
redir @http https://{host}{uri} permanent
reverse_proxy 127.0.0.1:9090 {
header_up Host {host}
header_up X-Forwarded-Host {host}
flush_interval -1
transport http {
read_timeout 300s
write_timeout 300s
}
}
}改完 sudo systemctl reload caddy 重载。
为什么要单独写块:
- 通配符块里的 WAF 可能改写请求头,导致 S3 签名校验失败(
SignatureDoesNotMatch) - S3 大文件上传需要关闭缓冲(
flush_interval -1)、加大超时 - Caddy 主机名匹配规则是具体域名优先于通配符,单独写块不会影响其他子域名
最后确认 *.xxx.com 的泛解析指向公网服务器 IP 就通了。
只读权限设置
建桶之后想给应用只读访问,用 mc 客户端最方便:
# 下载 mc(ARM64)
wget https://dl.min.io/client/mc/release/linux-arm64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
# 添加别名
mc alias set my-silo http://localhost:9000 YOUR_ACCESS_KEY YOUR_SECRET_KEY
# 设置只读(允许下载,不允许上传/删除)
mc anonymous set download my-silo/你的桶名如果还想更严格一点——只允许下载、连列目录都不行,就写个自定义策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadOnlyAccess",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::你的桶名/*"]
}
]
}mc anonymous set-json my-silo/你的桶名 readonly-policy.json策略里只有 s3:GetObject,没有 s3:ListBucket,用户无法列出桶内文件,只能通过确切 URL 访问,适合做静态资源托管。
日常维护
# 看日志
docker logs silo --tail 100
# 看资源占用
free -h
docker stats silo --no-stream
# 备份(eMMC 单盘无冗余,重要数据定期同步出去)
mc mirror my-silo/你的桶名 /backup/local-dir
# 升级
docker pull pgsty/silo:新版本号
docker stop silo && docker rm silo
# 用新版本号重新执行 docker run 即可总结
折腾下来几个结论:
- CM311-1a(2GB)跑 Silo 完全够用,实测内存占用约 136MB。
- eMMC 部署无需额外分区,Silo 支持任意空目录,这是它相对 RustFS 最大的优势。
- FRP 子域名 + Caddy 单独站点块是内网盒子对外暴露 S3 的最佳组合,记得绕开 WAF。
- 只读权限用
mc anonymous set download或者自定义 JSON 策略,按场景选。
当然也有局限:公网服务器就一根 5M 小水管,传个小文件没问题,大文件就别想了。不过平时作为应用程序的 S3 存储,这点带宽完全够用了,又多了10G免费存储。
