What Garage is, and what it is not
Garage is an S3-compatible object store designed for small self-hosted deployments, optionally spread across sites. It fits in one container, needs no database server beside it, and on a single-node deployment it idles at a few megabytes of memory.
What it is not should be said straight away: Garage has no web console. Administration goes through the garage command-line tool and an HTTP admin API. That is a design choice, not a missing feature — the daemon stays small and its operational surface narrow. Community projects offer a browser interface on top of the admin API if you want one.
If you are reading this because MinIO removed its console from the community edition in 2025 — then stopped publishing community Docker images altogether — the honest answer is that Garage will not give that console back. What it gives you instead is a project whose AGPLv3 licence holds no feature back for a paid edition.
Preparing the server
Garage runs in a container. On an up-to-date Debian or Ubuntu VPS, all you need is Docker and the Compose plugin:
curl -fsSL https://get.docker.com | shOn sizing, Garage itself is frugal: what decides is the volume of data you store, not the service. An entry-level VPS is enough to run the daemon; size the disk for what you intend to put in it, and keep in mind that a single node holds one copy of your objects.
The minimal configuration
Garage reads a garage.toml file. For a single node the essentials fit in a few lines — note replication_factor = 1, which states plainly that there is no replication:
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"
replication_factor = 1
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "<64 hexadecimal characters>"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.garage.localhost"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "<admin token>"The rpc_secret must be 32 bytes, i.e. 64 hexadecimal characters: openssl rand -hex 32.
Starting up, and getting your S3 credentials
Since version 2.3, Garage can bring up a single-node cluster and create its first bucket on its own, from environment variables. That is what removes the manual layout assign / layout apply / bucket create / key create sequence:
services:
garage:
image: dxflrs/garage:v2.3.0
restart: unless-stopped
command: ["/garage", "-c", "/etc/garage/garage.toml", "server", "--single-node", "--default-bucket"]
environment:
GARAGE_DEFAULT_BUCKET: my-bucket
GARAGE_DEFAULT_ACCESS_KEY: GK...
GARAGE_DEFAULT_SECRET_KEY: ...
ports:
- "127.0.0.1:3900:3900"
volumes:
- ./config:/etc/garage
- garage-meta:/var/lib/garage/meta
- garage-data:/var/lib/garage/dataTwo traps are worth naming, because each costs half an hour. The image is distroless: it has no shell, and its entrypoint is empty — so the command must name the binary by absolute path (/garage) and the config file (-c), otherwise the container loops on No such file or directory. And the S3 access key must have the shape Garage expects: the GK prefix followed by 30 hexadecimal characters.
Checking that it works
An anonymous call on the S3 API must answer 403, with the message Garage does not support anonymous access yet. That is the good sign: the service is alive and refuses an unsigned request.
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3900/
# 403 → the API is answeringThe admin API answers 200 with the token:
curl -H "Authorization: Bearer $ADMIN_TOKEN" http://127.0.0.1:3903/v2/ListBucketsFrom there any S3 client works: aws --endpoint-url, mc, rclone, or restic directly for your backups.
What to keep in mind
A single node is not redundancy. Garage can replicate across several machines, possibly across sites — that is its very purpose. But as long as you have one node, your objects exist in a single copy, on a single disk. Keep the backup discipline you would have had anyway.
Expose the API behind a domain and TLS, not on a bare IP: publish the port on the loopback interface and let nginx handle the proxying and the certificate. That is what the Marketplace one-click install does.
S3 compatibility covers the common surface, not every AWS-specific extension. Standard clients, SDKs and backup tools work unchanged; if you depend on an unusual call, check it against the project documentation before migrating.