[{"data":1,"prerenderedAt":56},["ShallowReactive",2],{"seo-verification":3,"blog-heberger-garage-s3-vps-en":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"id":7,"slug":8,"title":9,"excerpt":10,"readTime":11,"views":12,"isPinned":13,"publishedAt":14,"category":15,"categories":21,"featuredImage":23,"bgImage":24,"posterImage":25,"relatedSolution":26,"intro":29,"sections":30,"ctaTitle":51,"ctaBody":52,"ctaButton":53,"ctaUrl":54,"relatedPosts":55},245,"heberger-garage-s3-vps","Host Garage on a VPS: S3 object storage that belongs to you","Garage is an S3-compatible object store written in Rust, light enough to run on a small VPS. Here is how to deploy it, what it does well, and what it does not do.",6,0,false,"2026-08-10T00:00:00+00:00",{"id":16,"name":17,"slug":18,"color":19,"icon":20},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[22],{"id":16,"name":17,"slug":18,"color":19,"icon":20},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fheberger-garage-s3-vps-poster.svg",{"categorySlug":27,"appSlug":28},"bases-de-donnees","garage","You want an S3 endpoint of your own — for restic backups, an application's uploads, or the origin of a static site — without opening an account at a cloud provider. Garage, built by the Deuxfleurs collective, does exactly that: a single Rust binary exposing an S3 API, frugal enough to sit alongside the rest of your server. This guide goes from nothing to your first uploaded object.",[31,35,38,42,45,48],{"type":32,"title":33,"body":34},"text","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.\n\nWhat 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.\n\nIf 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.",{"type":32,"title":36,"body":37},"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:\n\n```bash\ncurl -fsSL https:\u002F\u002Fget.docker.com | sh\n```\n\nOn 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.",{"type":39,"title":40,"body":41},"code","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:\n\n```toml\nmetadata_dir = \"\u002Fvar\u002Flib\u002Fgarage\u002Fmeta\"\ndata_dir = \"\u002Fvar\u002Flib\u002Fgarage\u002Fdata\"\ndb_engine = \"sqlite\"\nreplication_factor = 1\n\nrpc_bind_addr = \"[::]:3901\"\nrpc_public_addr = \"127.0.0.1:3901\"\nrpc_secret = \"\u003C64 hexadecimal characters>\"\n\n[s3_api]\ns3_region = \"garage\"\napi_bind_addr = \"[::]:3900\"\nroot_domain = \".s3.garage.localhost\"\n\n[admin]\napi_bind_addr = \"[::]:3903\"\nadmin_token = \"\u003Cadmin token>\"\n```\n\nThe `rpc_secret` must be 32 bytes, i.e. 64 hexadecimal characters: `openssl rand -hex 32`.",{"type":39,"title":43,"body":44},"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` \u002F `layout apply` \u002F `bucket create` \u002F `key create` sequence:\n\n```yaml\nservices:\n  garage:\n    image: dxflrs\u002Fgarage:v2.3.0\n    restart: unless-stopped\n    command: [\"\u002Fgarage\", \"-c\", \"\u002Fetc\u002Fgarage\u002Fgarage.toml\", \"server\", \"--single-node\", \"--default-bucket\"]\n    environment:\n      GARAGE_DEFAULT_BUCKET: my-bucket\n      GARAGE_DEFAULT_ACCESS_KEY: GK...\n      GARAGE_DEFAULT_SECRET_KEY: ...\n    ports:\n      - \"127.0.0.1:3900:3900\"\n    volumes:\n      - .\u002Fconfig:\u002Fetc\u002Fgarage\n      - garage-meta:\u002Fvar\u002Flib\u002Fgarage\u002Fmeta\n      - garage-data:\u002Fvar\u002Flib\u002Fgarage\u002Fdata\n```\n\nTwo 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 (`\u002Fgarage`) 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.",{"type":32,"title":46,"body":47},"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.\n\n```bash\ncurl -s -o \u002Fdev\u002Fnull -w '%{http_code}\\n' http:\u002F\u002F127.0.0.1:3900\u002F\n# 403 → the API is answering\n```\n\nThe admin API answers 200 with the token:\n\n```bash\ncurl -H \"Authorization: Bearer $ADMIN_TOKEN\" http:\u002F\u002F127.0.0.1:3903\u002Fv2\u002FListBuckets\n```\n\nFrom there any S3 client works: `aws --endpoint-url`, `mc`, `rclone`, or restic directly for your backups.",{"type":32,"title":49,"body":50},"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.\n\n**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.\n\n**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.","Garage in one click on your VPS","The ServOrbit Marketplace installs Garage, creates its bucket and your S3 credentials at first boot. All that is left is pointing your client at it.","Deploy Garage","\u002Fmarketplace\u002Fbases-de-donnees\u002Fgarage",[],1786455117247]