Garage v2.4.1 Docker Compose 部署指南

使用官方 dxflrs/garage:v2.4.1 镜像通过 Docker Compose 部署单节点 Garage 对象存储,覆盖 compose 文件编写、配置挂载、数据卷持久化、集群初始化、S3 端到端验证与常用运维命令

GarageGarage对象存储S3 兼容DockerDocker Compose2026/10/17

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.1v2.4.1本文采用,生产推荐固定 tag
dxflrs/garage:v2.4.0v2.4.0上一维护版本
dxflrs/garage:latest滚动最新不推荐生产

关键差异:固定 tag 可复现部署,latest 随官方推送漂移,升级不可控。

三、前置条件

  1. 宿主机已安装 Docker Engine 与 Docker Compose v2(docker compose version 可用);
  2. 端口 3900-3903 未被占用:ss -lntp | grep -E '3900|3901|3902|3903' 应无输出;
  3. 部署目录: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.tomlGarage 全局默认值即此
GARAGE_METADATA_DIRmetadata_dir/var/lib/garage/meta元数据目录
GARAGE_DATA_DIRdata_dir/var/lib/garage/data数据块目录
GARAGE_DB_ENGINEdb_enginefjall元数据引擎
GARAGE_REPLICATION_FACTORreplication_factor1副本数
GARAGE_RPC_SECRETrpc_secret32 字节 hex集群密钥
GARAGE_S3_API_API_BIND_ADDRs3_api.api_bind_addr[::]:3900S3 监听
GARAGE_ADMIN_API_BIND_ADDRadmin.api_bind_addr[::]:3903Admin 监听
GARAGE_ADMIN_TOKENadmin.admin_token见下Admin API 令牌
GARAGE_ALLOW_WORLD_READABLE_SECRETSallow_world_readable_secretsfalse放宽密钥文件权限检查

敏感值推荐用 _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(连数据卷一起删除,对象数据永久丢失,谨慎)。

十二、参考链接