Qué es Garage y qué no es
Garage es un almacén de objetos compatible con S3 diseñado para despliegues autoalojados de pequeño tamaño, opcionalmente distribuidos en varios sitios. Corre en un contenedor, no necesita una base de datos adyacente, y en un despliegue de un solo nodo consume unos pocos megabytes de memoria en reposo.
Lo que no es, hay que decirlo desde el principio: Garage no tiene consola web. La administración se realiza mediante la herramienta de línea de comandos garage y una API de administración HTTP. No es una función omitida — es una decisión deliberada para mantener el servicio pequeño y su superficie de ataque estrecha. Proyectos de la comunidad ofrecen una interfaz en el navegador sobre la API de administración si la necesitas.
Si buscas este punto porque MinIO retiró su consola de la edición comunitaria en 2025 — y después dejó de publicar sus imágenes Docker comunitarias — la respuesta honesta es que Garage no te devolverá esa consola. Sí te da un proyecto cuya licencia AGPLv3 no reserva ninguna función a una edición de pago.
Lo que Garage hace bien en un VPS
- API S3 estándar: compatible con
awsCLI,rclone,mc,restic, SDKs de Python/Go/Rust y prácticamente todos los clientes S3 del mercado. - Huella de memoria mínima: unos pocos megabytes en reposo — convive sin fricción con un servidor web, una base de datos o un proxy inverso en el mismo VPS.
- Sin dependencias externas: ni PostgreSQL, ni Redis, ni etcd. El motor de metadatos está embebido (LMDB o SQLite).
- Replicación opcional: en modo de un nodo basta un disco; en modo multinodo Garage replica objetos entre máquinas, incluso en sitios distintos.
- Licencia AGPLv3 sin restricciones: ninguna función reservada a una edición de pago, sin límite de volumen ni de número de buckets.
- Subdominios virtuales: Garage gestiona el enrutamiento
<bucket>.s3.tu-dominio.com, que algunos clientes S3 y SDKs requieren.
Requisitos previos: dimensionar tu VPS para un storage bucket
Garage en sí es frugal — es el volumen de datos que almacenas el que determina el tamaño del disco, no el servicio. Un VPS de entrada es suficiente para ejecutar el daemon. Para cargas de trabajo habituales (copias de seguridad de aplicaciones, assets de un sitio):
- CPU: 1 vCPU es suficiente; Garage es ligero en cómputo.
- RAM: 512 MB disponibles son cómodos; el motor LMDB mantiene su índice en archivos mapeados en memoria.
- Disco: SSD NVMe del tamaño de tus datos más un 20 % de margen para metadatos. Un nodo único guarda una sola copia de tus objetos — planifica en consecuencia.
- SO: Debian 12 o Ubuntu 22.04 LTS con Docker y el plugin Compose instalados.
Para instalar Docker en un solo comando:
curl -fsSL https://get.docker.com | shConfiguración mínima del storage bucket
Garage lee un archivo garage.toml. Para un nodo único, lo esencial cabe en pocas líneas — fíjate en replication_factor = 1, que indica explícitamente que no hay replicación:
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 caracteres hexadecimales>"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.tu-dominio.com"
[admin]
api_bind_addr = "[::]:3903"
admin_token = "<token de administración>"El rpc_secret debe tener 32 bytes, es decir, 64 caracteres hexadecimales: openssl rand -hex 32.
Desplegar Garage y crear tu primer bucket S3
Crear la estructura de directorios
Crea un directorio de trabajo y el archivo de configuración:
mkdir -p /opt/garage/config openssl rand -hex 32 # → pega como rpc_secret openssl rand -base64 32 | tr -d '=' | head -c 40 # → admin_tokenEscribe
garage.tomlen/opt/garage/config/reemplazando los dos tokens generados.Escribir el Compose y arrancar
Desde la versión 2.3, Garage puede inicializar un clúster de un nodo y crear su primer bucket automáticamente a partir de variables de entorno. Esto evita la secuencia manual
layout assign/layout apply/bucket create/key create: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: mi-bucket GARAGE_DEFAULT_ACCESS_KEY: GK<30 hex> GARAGE_DEFAULT_SECRET_KEY: <64 hex> ports: - "127.0.0.1:3900:3900" - "127.0.0.1:3903:3903" volumes: - ./config:/etc/garage - garage-meta:/var/lib/garage/meta - garage-data:/var/lib/garage/data volumes: garage-meta: garage-data:La imagen es distroless: sin shell, entrypoint vacío. El comando debe nombrar el binario por ruta absoluta (
/garage) y pasar el archivo de configuración (-c). La clave de acceso S3 debe serGKseguida de exactamente 30 caracteres hexadecimales.docker compose up -dVerificar que la API responde
Una llamada anónima a la API S3 debe devolver 403 — la señal correcta de que el servicio está activo y rechaza peticiones sin firmar:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3900/ # 403 → la API respondeLa API de administración devuelve 200 con el token:
curl -H "Authorization: Bearer $ADMIN_TOKEN" http://127.0.0.1:3903/v2/ListBucketsExponer la API detrás de nginx y TLS
Nunca publiques el puerto 3900 directamente en la interfaz pública. Enlázalo a localhost y deja que nginx gestione el proxy y el certificado TLS:
server { listen 443 ssl; server_name s3.tu-dominio.com *.s3.tu-dominio.com; ssl_certificate /etc/letsencrypt/live/s3.tu-dominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/s3.tu-dominio.com/privkey.pem; location / { proxy_pass http://127.0.0.1:3900; proxy_set_header Host $host; } }Probar con un cliente S3
Con las variables de entorno configuradas, la CLI
awsfunciona sin modificaciones:export AWS_ACCESS_KEY_ID=GK... export AWS_SECRET_ACCESS_KEY=... export AWS_DEFAULT_REGION=garage aws --endpoint-url https://s3.tu-dominio.com s3 ls aws --endpoint-url https://s3.tu-dominio.com s3 cp miarchivo.txt s3://mi-bucket/Para restic, configura
RESTIC_REPOSITORY=s3:https://s3.tu-dominio.com/mi-buckety ejecutarestic init.
Casos de uso habituales de un storage bucket S3 autoalojado
Un storage bucket Garage en un VPS cubre varias necesidades habituales sin depender de ninguna nube externa.
Qué se despliega detrás de Garage
- Copias de seguridad con restic o Borg: configura
RESTIC_REPOSITORY=s3:https://s3.tu-dominio.com/backups. La compatibilidad S3 en restic es nativa y no requiere plugins. - Origen de sitio estático: almacena los assets compilados del frontend y sírvelos con nginx o Cloudflare en modo proxy.
- Subida de archivos de aplicaciones: las aplicaciones Laravel, Django o Rails escriben en Garage a través de su SDK S3 habitual — solo cambia el endpoint.
- Artefactos de CI/CD: GitHub Actions o GitLab CI suben artefactos de build a Garage con
aws s3 cp, igual que con AWS S3. - Archivo de logs y métricas: Loki, Vector o Fluentd pueden escribir en un almacén de objetos compatible con S3 para archivo a largo plazo.
- Compartir archivos entre servicios: dos contenedores en el mismo o diferente VPS acceden al mismo bucket a través de la API S3, sin montaje NFS.
Garage vs alternativas S3 autoalojadas
Desplace la tabla
| Criterio | Garage | MinIO (comunitario) |
|---|---|---|
| Licencia | AGPLv3 — sin restricción de uso | AGPLv3, pero consola retirada de la edición libre en 2025 |
| Imágenes Docker | Publicadas activamente en Docker Hub (`dxflrs/garage`) | Imágenes comunitarias discontinuadas en Docker Hub en 2025 |
| Consola web | Ausente (CLI + API de administración HTTP) | Consola eliminada de la edición comunitaria |
| Multi-sitio | Diseñado nativamente para zonas geográficas | Posible pero requiere un clúster dedicado |
| Huella de memoria | Unos pocos MB en reposo | Varias decenas de MB como mínimo |
| Compatibilidad S3 | Buena en la superficie habitual | Muy amplia, incluyendo extensiones propias de AWS |
Buckets, claves de acceso y permisos
Garage gestiona el acceso a nivel de clave: cada clave S3 puede autorizarse en uno o varios buckets, de solo lectura o lectura-escritura. Para copias de seguridad automatizadas, crea una clave dedicada con acceso únicamente al bucket de backup — no a todo el servidor.
El comando garage key create <nombre> genera una clave, y garage bucket allow --key <id> --read --write <bucket> le otorga los derechos. También puedes usar la API de administración HTTP para automatizarlo en un script.
Lo que hay que tener presente
Un nodo único no es redundancia. Garage puede replicar entre varias máquinas, incluso en sitios distintos — ese es su objetivo de diseño. Pero mientras tengas un solo nodo, tus objetos existen en una única copia sobre un único disco. Mantén la disciplina de copias de seguridad que aplicarías de todos modos.
Expón la API detrás de un dominio y TLS, no sobre una IP desnuda. Es a la vez un requisito de seguridad y una necesidad práctica: varios clientes S3 se niegan a funcionar sin TLS, y el enrutamiento por subdominio de bucket requiere un certificado wildcard.
La compatibilidad S3 cubre la superficie habitual, no cada extensión propia de AWS. Los clientes, bibliotecas y herramientas de backup estándar funcionan sin modificación; si dependes de una llamada inusual, compruébalo en la documentación del proyecto antes de migrar.
Vigila el espacio en disco. Un bucket de copias de seguridad que crece sin política de retención llena el disco silenciosamente. Configura una regla de ciclo de vida o un cron que elimine snapshots antiguos mediante garage bucket lifecycle.