Garage v2.4.1 Docker Compose 部署指南
使用官方 dxflrs/garage:v2.4.1 镜像通过 Docker Compose 部署单节点 Garage 对象存储,覆盖 compose 文件编写、配置挂载、数据卷持久化、集群初始化、S3 端到端验证与常用运维命令
Garage v2.4.1 Docker Compose 部署指南
目标:使用官方
dxflrs/garage:v2.4.1镜像,通过 Docker Compose 一键部署单节点 Garage S3 兼容对象存储,完成配置挂载、数据卷持久化、集群初始化、S3 上传下载端到端验证与日常运维操作。已在 Docker 29.8.0 + Docker Compose v2 环境实测通过。
一、环境信息
本文所有命令与回显均在以下环境实测采集:
- 宿主系统:Ubuntu 22.04(x86_64),Docker Engine 29.8.0,Docker Compose v2
- Garage 版本:v2.4.1(官方镜像
dxflrs/garage:v2.4.1) - 镜像信息:镜像 ID
9c96caa2612d,CONTENT SIZE 28.1MB - 部署目录:
/opt/garage(garage.toml 与 compose.yaml 所在地) - 数据卷:
garage-meta(元数据)、garage-data(对象数据) - 端口映射:3900(S3 API)、3901(RPC)、3902(网站)、3903(Admin API)
本文是容器化部署教程,以下 Docker/Compose 操作均针对部署 Garage 本身;如需在物理机直接安装 Garage,见《Garage v2.4.1 Ubuntu 22.04 安装指南》。
💡 技术拓展:容器化对象存储的持久化方案对比——
方案 写法 特点 命名卷(named volume) volumes: garage-meta:/var/lib/garage/meta由 Docker 管理、可备份迁移,Compose 首选 绑定挂载(bind mount) ./data/meta:/var/lib/garage/meta路径直观、宿主可直接查看,注意 UID 权限 临时卷(tmpfs) tmpfs: /var/lib/garage/data重启即丢,仅测试 本文采用命名卷:Garage 镜像内以 root 运行(官方镜像固定),命名卷无需关心宿主目录属主;
docker compose down -v才会删卷,down/restart均安全。
二、镜像选型说明
Garage 官方镜像托管在 Docker Hub dxflrs/garage,tag 与版本一一对应。拉取固定版本 tag(勿用 latest,官方不保证 latest 行为):
docker pull dxflrs/garage:v2.4.1
实测回显(宿主已配置镜像加速/代理时):
v2.4.1: Pulling from dxflrs/garage
Digest: sha256:9c96caa2612d3411acc5b0e6701fb238dbfba33e533a6d7d3d811a4b12d0d020
Status: Downloaded newer image for dxflrs/garage:v2.4.1
docker.io/dxflrs/garage:v2.4.1
确认镜像默认启动命令:
docker inspect dxflrs/garage:v2.4.1 --format '{{json .Config.Cmd}}'
实测回显:
["/garage","server"]
即容器启动即运行 garage server,配置文件默认读取 /etc/garage.toml——这就是下面 compose 挂载配置文件的依据。
| 镜像 tag | 对应版本 | 说明 |
|---|---|---|
| dxflrs/garage:v2.4.1 | v2.4.1 | 本文采用,生产推荐固定 tag |
| dxflrs/garage:v2.4.0 | v2.4.0 | 上一维护版本 |
| dxflrs/garage:latest | 滚动最新 | 不推荐生产 |
关键差异:固定 tag 可复现部署,latest 随官方推送漂移,升级不可控。
三、前置条件
- 宿主机已安装 Docker Engine 与 Docker Compose v2(
docker compose version可用); - 端口 3900-3903 未被占用:
ss -lntp | grep -E '3900|3901|3902|3903'应无输出; - 部署目录:
mkdir -p /opt/garage。
四、部署步骤
4.1 编写 garage.toml
创建 /opt/garage/garage.toml(rpc_secret 用 openssl rand -hex 32 重新生成,本文使用实测值):
mkdir -p /opt/garage && cd /opt/garage
openssl rand -hex 32
实测回显:
9aeea1964498f98883c8d16a2ed241c7acf43dd6fd0f6e7dbf46856044e3d158
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "fjall"
replication_factor = 1
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "9aeea1964498f98883c8d16a2ed241c7acf43dd6fd0f6e7dbf46856044e3d158"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.garage.localhost"
[s3_web]
bind_addr = "[::]:3902"
root_domain = ".web.garage.localhost"
index = "index.html"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "q1w2e3r4-admin"
逐项说明:容器内路径 /var/lib/garage/{meta,data} 与官方镜像工作目录一致,两个路径分别落到 compose 的两个数据卷;replication_factor = 1 为单节点;rpc_public_addr 单机写 127.0.0.1:3901 即可(多节点容器组网见进阶篇);其余参数含义见《Garage v2.4.1 配置参数详解》。
4.2 编写 compose.yaml
创建 /opt/garage/compose.yaml:
services:
garage:
image: dxflrs/garage:v2.4.1
container_name: garage
hostname: garage
volumes:
- ./garage.toml:/etc/garage.toml
- garage-meta:/var/lib/garage/meta
- garage-data:/var/lib/garage/data
ports:
- "3900:3900"
- "3901:3901"
- "3902:3902"
- "3903:3903"
restart: unless-stopped
volumes:
garage-meta:
garage-data:
逐项说明:container_name: garage 固定名称便于 docker exec;./garage.toml:/etc/garage.toml 挂载配置(只读需求可在路径后加 :ro);两个命名卷持久化元数据与数据;3900-3903 四个端口全部映射(仅本机使用可绑 127.0.0.1:3900:3900);restart: unless-stopped 宿主重启后自动拉起。
4.3 启动服务
cd /opt/garage && docker compose up -d
实测回显:
Container garage Starting
Container garage Started
查看运行状态:
docker compose ps
实测回显:
NAME IMAGE STATUS PORTS
garage dxflrs/garage:v2.4.1 Up 4 seconds 0.0.0.0:3900->3900/tcp, [::]:3900->3900/tcp, 0.0.0.0:3901->3901/tcp, [::]:3901->3901/tcp, 0.0.0.0:3902->3902/tcp, [::]:3902->3902/tcp, 0.0.0.0:3903->3903/tcp, [::]:3903->3903/tcp
查看启动日志确认监听:
docker compose logs garage | grep -E 'listening|Node ID' | head -6
实测回显:
garage | 2026-10-17T04:44:31.709184Z INFO garage::server: Loading configuration from /etc/garage.toml...
garage | 2026-10-17T04:44:31.709767Z INFO garage::server: Initializing Garage main data store...
garage | 2026-10-17T04:44:31.709819Z INFO garage_model::garage: Opening database...
garage | 2026-10-17T04:44:31.709836Z INFO garage_db::fjall_adapter: Opening Fjall database at: /var/lib/garage/meta/db.fjall
日志前缀 garage | 为 compose 格式;Opening Fjall database 确认配置挂载生效、元数据落卷。
4.4 集群初始化(layout 分配)
官方镜像内二进制路径为 /garage(不在 PATH 中,docker exec 需写全路径)。查看节点并分配角色:
docker exec garage /garage status
实测回显:
==== HEALTHY NODES ====
ID Hostname Address Tags Zone Capacity DataAvail Version
1ad3d5461568bd51 garage 127.0.0.1:3901 NO ROLE ASSIGNED v2.4.1
docker exec garage /garage layout assign -z dc1 -c 1G 1ad3d5461568bd51
docker exec garage /garage layout apply --version 1
layout assign 实测回显:
Role changes are staged but not yet committed.
Use `garage layout show` to view staged role changes,
and `garage layout apply` to enact staged changes.
layout apply 实测回显:
New cluster layout with updated role assignment has been applied in cluster.
Data will now be moved around between nodes accordingly.
再次确认角色生效:
docker exec garage /garage status
实测回显:
==== HEALTHY NODES ====
ID Hostname Address Tags Zone Capacity DataAvail Version
1ad3d5461568bd51 garage 127.0.0.1:3901 [] dc1 953.7 MiB 94.7 GiB (12.1%) v2.4.1
4.5 创建 Bucket 与访问密钥
docker exec garage /garage bucket create compose-demo
docker exec garage /garage key create compose-key
docker exec garage /garage bucket allow --read --write --owner compose-demo --key compose-key
bucket create 实测回显:
==== BUCKET INFORMATION ====
Bucket: 2e87f33fce7bca318ba487ea14859dbf2f8b65b95f08aaa792e95427eb795f79
Created: 2026-10-17 04:45:10.559 +00:00
Size: 0 B (0 B)
Objects: 0
Website access: false
Global alias: compose-demo
key create 实测回显:
==== ACCESS KEY INFORMATION ====
Key ID: GK5f4260e6e08dba6c5d7d1afd
Key name: compose-key
Secret key: 8969f7b0352cc08df9b7db4a8a9205f61f154597ba23e9af660d707d1eacce07
Created: 2026-10-17 04:45:11.292 +00:00
Validity: valid
Expiration: never
Can create buckets: false
bucket allow 实测回显(节选):
==== KEYS FOR THIS BUCKET ====
Permissions Access key Local aliases
RWO GK5f4260e6e08dba6c5d7d1afd compose-key
4.6 S3 端到端验证
在宿主机或任意能访问 3900 端口的机器上用 AWS CLI 验证(AWS CLI 安装见《Garage v2.4.1 Ubuntu 22.04 安装指南》4.9 节;客户端与 Garage 同机时 endpoint 用 http://127.0.0.1:3900):
aws configure set aws_access_key_id GK5f4260e6e08dba6c5d7d1afd
aws configure set aws_secret_access_key 8969f7b0352cc08df9b7db4a8a9205f61f154597ba23e9af660d707d1eacce07
aws configure set default.region garage
实测回显(本例从同一宿主机网段另一台服务器的视角经端口映射访问;endpoint 写部署机实际可达 IP,本文实测环境为 172.17.0.3):
aws --endpoint-url http://172.17.0.3:3900 s3 ls
2026-10-17 04:45:15 compose-demo
上传/列举/下载:
echo compose-s3-test > /root/compose-test.txt
aws --endpoint-url http://172.17.0.3:3900 s3 cp /root/compose-test.txt s3://compose-demo/
aws --endpoint-url http://172.17.0.3:3900 s3 ls s3://compose-demo
aws --endpoint-url http://172.17.0.3:3900 s3 cp s3://compose-demo/compose-test.txt /root/ct-back.txt
cat /root/ct-back.txt
实测回显:
upload: root/compose-test.txt to s3://compose-demo/compose-test.txt
2026-10-17 04:45:49 16 compose-test.txt
download: s3://compose-demo/compose-test.txt to root/ct-back.txt
compose-s3-test
4.7 数据持久化验证
重启容器后验证数据与 bucket 保留:
cd /opt/garage && docker compose restart
实测回显:
Container garage Started
docker exec garage /garage bucket list
实测回显:
2e87f33fce7bca31 2026-10-17 compose-demo
bucket 与对象均保留,命名卷持久化生效。
五、数据持久化说明
garage-meta卷:元数据(Fjall 数据库db.fjall、集群布局cluster_layout、节点密钥node_key等)。此卷丢失等于集群身份丢失,务必纳入备份;garage-data卷:对象数据块(按内容寻址分块存储,默认块大小 1MiB);- 查看卷在宿主的实际位置:
docker volume inspect garage_garage-meta(compose 项目前缀默认为目录名); - 备份:
docker run --rm -v garage_garage-meta:/meta -v /backup:/backup busybox tar czf /backup/garage-meta.tar.gz -C /meta .(停止写入时执行更安全)。
六、环境变量表
Garage 支持用环境变量覆盖 garage.toml 的同名配置,规则为 GARAGE_ + 大写路径(分隔符为下划线)。常用项:
| 环境变量 | 覆盖的配置项 | 示例值 | 说明 |
|---|---|---|---|
| GARAGE_CONFIG_FILE | 配置文件路径 | /etc/garage.toml | Garage 全局默认值即此 |
| GARAGE_METADATA_DIR | metadata_dir | /var/lib/garage/meta | 元数据目录 |
| GARAGE_DATA_DIR | data_dir | /var/lib/garage/data | 数据块目录 |
| GARAGE_DB_ENGINE | db_engine | fjall | 元数据引擎 |
| GARAGE_REPLICATION_FACTOR | replication_factor | 1 | 副本数 |
| GARAGE_RPC_SECRET | rpc_secret | 32 字节 hex | 集群密钥 |
| GARAGE_S3_API_API_BIND_ADDR | s3_api.api_bind_addr | [::]:3900 | S3 监听 |
| GARAGE_ADMIN_API_BIND_ADDR | admin.api_bind_addr | [::]:3903 | Admin 监听 |
| GARAGE_ADMIN_TOKEN | admin.admin_token | 见下 | Admin API 令牌 |
| GARAGE_ALLOW_WORLD_READABLE_SECRETS | allow_world_readable_secrets | false | 放宽密钥文件权限检查 |
敏感值推荐用 _FILE 后缀变量从文件读取(如 GARAGE_RPC_SECRET_FILE=/run/secrets/rpc_secret),避免密钥出现在 compose 文件与环境变量列表中。
七、配置参数说明
容器化部署时 garage.toml 的完整参数含义与物理机一致,重点核对三项:
replication_factor:单节点必须为 1;写成 3 而只有 1 个节点会在layout apply时报The number of nodes with positive capacity (0) is smaller than the replication factor;rpc_public_addr:单机127.0.0.1:3901;若后续把此容器加入多节点集群,需改为容器网络的可达地址;db_engine:默认fjall,低内存设备可改lmdb/sqlite(引擎对比见《Garage v2.4.1 配置参数详解》)。
⚠️ 注意:v1.x 旧教程里的
replication_mode = "none"写法在 v2.4.1 会直接启动失败,报Error: The legacy replication_mode is no longer supported。
八、配置文件挂载说明
- 挂载点固定为
/etc/garage.toml(镜像内garage server默认读取路径),bind mount 与配置热修改:改完执行docker compose restart garage生效; - 校验挂载是否生效:
docker exec garage /garage status能正常返回且日志显示Loading configuration from /etc/garage.toml...; - 只读挂载:
./garage.toml:/etc/garage.toml:ro,防止容器内误改。
九、等价 docker run 命令
不使用 Compose 时,以下命令与上文 compose.yaml 等价:
docker volume create garage-meta
docker volume create garage-data
docker run -d --name garage \
--hostname garage \
-v /opt/garage/garage.toml:/etc/garage.toml \
-v garage-meta:/var/lib/garage/meta \
-v garage-data:/var/lib/garage/data \
-p 3900:3900 -p 3901:3901 -p 3902:3902 -p 3903:3903 \
--restart unless-stopped \
dxflrs/garage:v2.4.1
生产环境建议仍用 Compose 管理,参数声明式可追溯。
十、常用运维命令
cd /opt/garage
# 查看状态与日志
docker compose ps
docker compose logs -f --tail 50 garage
# 停止/启动/重启
docker compose stop
docker compose start
docker compose restart
# 进入 Garage 内部执行管理命令(注意二进制路径为 /garage)
docker exec garage /garage status
docker exec garage /garage bucket list
docker exec garage /garage key list
docker exec garage /garage health
# 升级镜像(数据卷保留)
docker compose pull
docker compose up -d
升级实测说明:docker compose pull && docker compose up -d 会用新镜像重建容器,命名卷 garage-meta/garage-data 不受影响,数据保留。
十一、常见问题
Q1:docker compose up 后容器立刻退出?
查日志 docker compose logs garage。最常见两类错误:配置文件挂载路径不对(日志显示 Failed to read config file /etc/garage.toml: No such file or directory,检查 compose 挂载行与文件名);v1.x 旧参数(replication_mode)导致启动即报错。
Q2:docker exec garage garage status 报 executable file not found?
官方镜像二进制在根目录 /garage,不在 PATH,需写全路径:docker exec garage /garage status(实测报错:OCI runtime exec failed: exec: "garage": executable file not found in $PATH)。
Q3:宿主机访问 3900 端口拒绝?
docker compose ps 确认端口映射列存在;ss -lntp | grep 3900 确认 docker-proxy 监听;防火墙放行 3900-3903。若 Garage 自身未监听,看启动日志是否报配置错误。
Q4:layout apply 报 The number of nodes with positive capacity (0) is smaller than the replication factor?
layout assign 尚未执行或 node ID 抄错。先 docker exec garage /garage status 复制正确短 ID,再 layout assign -z dc1 -c 1G <ID>,最后 layout apply --version 1(version 号每次递增)。
Q5:如何彻底删除部署?
docker compose down(保留数据卷);docker compose down -v(连数据卷一起删除,对象数据永久丢失,谨慎)。