Как установить и настроить Garage на VPS
Если вам нужно S3-совместимое хранилище, растянутое на несколько дата-центров, MinIO быстро упирается в то, что его модель репликации рассчитана в первую очередь на кластер в одной сети с низкой задержкой. Garage — проект французской ассоциации Deuxfleurs — написан под другой сценарий: узлы в разных городах и странах, разный объём диска, сеть похуже локальной. Ниже — как поднять Garage на одном VPS для старта и масштабировать его до геораспределённого кластера.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Garage и чем он отличается от MinIO
Garage — это S3-совместимое объектное хранилище на Rust, сделанное для self-hosted инфраструктуры небольших сообществ, которым нужна отказоустойчивость без дорогого железа и без выделенной быстрой сети между узлами. Ключевая идея — явное разделение узлов на зоны (zone): вы говорите Garage, какой узел в каком дата-центре стоит, а хранилище само следит, чтобы копии объекта не оседали в одной зоне.
Чем это отличается от MinIO на практике:
- MinIO в распределённом режиме ожидает erasure coding по дискам примерно одинакового размера и чувствителен к задержкам между узлами — рекомендуемый сценарий это один ЦОД или очень качественный канал между площадками.
- Garage использует репликацию (по умолчанию 3 копии), а не erasure coding, и проектировался для узлов с разным объёмом диска и сетью похуже — вплоть до обычного VPS в другой стране.
- Бинарник Garage занимает единицы мегабайт, зависимостей почти нет, метаданные в LMDB или SQLite — поднять его на VPS с 1 ГБ RAM реально для небольшой нагрузки.
- Из коробки нет консоли уровня MinIO Console — управление через CLI (
garage) и небольшой Admin API. - Garage моложе и проще по функциональности: нет lifecycle-политик уровня MinIO, часть расширений S3 API не поддержана — для PUT/GET/DELETE, presigned URL и статического хостинга сайта этого достаточно.
Если вам нужен один быстрый узел с полным набором enterprise-фич — почитайте статью про установку MinIO на VPS. Если задача — три недорогих узла в разных локациях (например, RU/US/UK), которые вместе переживают падение любого одного дата-центра, — Garage подходит лучше.
Установка Garage на VPS
Garage распространяется статическим бинарником под Linux (amd64 и arm64) и как Docker-образ dxflrs/garage. Возьмём вариант с systemd-сервисом — он проще в диагностике на голом VPS, чем контейнер, хотя если у вас уже стек в Docker Compose, образ dxflrs/garage встанет туда так же, как любой другой сервис.
Скачайте актуальный релиз с официального Git-репозитория проекта (git.deuxfleurs.fr/Deuxfleurs/garage) — берите последний стабильный тег ветки 1.x, а не main:
uname -m
# x86_64 или aarch64
ARCH=x86_64-unknown-linux-musl # для arm64: aarch64-unknown-linux-musl
VERSION=v1.0.1 # проверьте актуальный тег на странице релизов
curl -L -o /usr/local/bin/garage \
"https://garagehq.deuxfleurs.fr/_releases/${VERSION}/${ARCH}/garage"
chmod +x /usr/local/bin/garage
garage --version
Создайте каталоги под метаданные и данные и системного пользователя:
useradd --system --no-create-home --shell /usr/sbin/nologin garage
mkdir -p /var/lib/garage/meta /var/lib/garage/data /etc/garage
chown -R garage:garage /var/lib/garage
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверКонфигурация garage.toml
Вся настройка узла — один TOML-файл. Сгенерируйте RPC-секрет (общий для всех узлов, по нему они аутентифицируют друг друга) и создайте /etc/garage/garage.toml:
openssl rand -hex 32
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "lmdb"
replication_factor = 3
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "203.0.113.10:3901" # внешний IP этого VPS
rpc_secret = "вставьте_hex_секрет_сюда"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:3900"
root_domain = ".s3.example.com"
[s3_web]
bind_addr = "[::]:3902"
root_domain = ".web.example.com"
index = "index.html"
[admin]
api_bind_addr = "127.0.0.1:3903"
admin_token = "второй_отдельный_секрет_для_admin_api"
Важные моменты:
rpc_public_addr— адрес, по которому другие узлы достучатся до текущего. Обычно это основной публичный IP; за NAT пробросьте порт 3901/tcp вручную.replication_factor = 3— объект переживёт потерю двух из трёх узлов. Для теста на одном VPS можно временно ставить 1, для боевого геокластера меньше трёх смысла не имеет.api_bind_addrв[s3_api]— сюда ходят S3-клиенты (aws-cli,rclone, SDK). Слушайте на127.0.0.1, если снаружи отдаёте через reverse-proxy с TLS (раздел ниже).[admin]— держите на loopback и закрывайте firewall'ом снаружи: через admin-токен управляют кластером целиком.
Пропишите systemd-юнит /etc/systemd/system/garage.service:
[Unit]
Description=Garage S3-compatible storage
After=network-online.target
[Service]
User=garage
Group=garage
ExecStart=/usr/local/bin/garage server -c /etc/garage/garage.toml
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now garage
systemctl status garage
Инициализация кластера и layout по зонам
Повторите установку и конфиг ещё на двух VPS — в идеале в разных локациях (например, RU, US, UK), с тем же rpc_secret, но своим rpc_public_addr на каждом. После запуска всех трёх узлов посмотрите их идентификаторы:
garage -c /etc/garage/garage.toml status
Каждый узел покажет свой Node ID (hex-строка) — на этом этапе узлы видят друг друга по RPC, но ещё не входят в layout. Если статус показывает только себя, проверьте, что порт 3901 открыт между серверами и что все три garage.toml используют один и тот же rpc_secret.
Соберите узлы в кластер и назначьте каждому зону и объём диска, который он отдаёт под данные:
# на любом из узлов, например на первом
garage -c /etc/garage/garage.toml layout assign -z ru -c 200G <node_id_1>
garage -c /etc/garage/garage.toml layout assign -z us -c 200G <node_id_2>
garage -c /etc/garage/garage.toml layout assign -z uk -c 200G <node_id_3>
garage -c /etc/garage/garage.toml layout show
garage -c /etc/garage/garage.toml layout apply --version 1
Флаг -z — это и есть зона: при репликации Garage старается класть копии объекта в разные зоны, а не просто на разные узлы. Значение -c — сколько места под данные узел отдаёт (может быть меньше реального диска, если сервер занят и другими задачами).
После layout apply кластер начинает балансировать данные — на пустом кластере мгновенно, на заполненном может занять время в зависимости от объёма и скорости сети между зонами. Прогресс видно через garage status и garage stats.
Добавление узла или смена объёма диска на существующем — снова layout assign + layout apply с новым номером версии. Убирать узел тоже нужно через layout (layout assign -z <zone> -c 0 <node_id> перед выключением), иначе Garage будет считать его данные временно недоступными, а не удалёнными осознанно.
Bucket, ключи доступа и S3 API
Создайте бакет и ключ доступа с правами на него:
garage -c /etc/garage/garage.toml bucket create my-bucket
garage -c /etc/garage/garage.toml key create my-app-key
# выведет Key ID и Secret Access Key — секрет показывается один раз, сохраните сразу
garage -c /etc/garage/garage.toml bucket allow \
--read --write my-bucket --key my-app-key
Проверьте доступ через aws-cli — Garage реализует достаточно S3 API, чтобы стандартные клиенты работали без доработок:
aws configure set aws_access_key_id <key_id> --profile garage
aws configure set aws_secret_access_key <secret> --profile garage
aws --endpoint-url http://127.0.0.1:3900 \
--profile garage --region garage \
s3 ls
echo "test" > /tmp/test.txt
aws --endpoint-url http://127.0.0.1:3900 \
--profile garage --region garage \
s3 cp /tmp/test.txt s3://my-bucket/test.txt
Так же подключается rclone (тип s3, provider Other, endpoint — ваш публичный адрес S3 API) — удобно для синка с локальной машины или миграции данных из MinIO rclone-ом «bucket в bucket».
Если бакет должен раздавать статику как обычный веб-хостинг — включите s3_web:
garage -c /etc/garage/garage.toml bucket website --allow my-bucket
и он станет доступен через [s3_web] эндпоинт по домену вида my-bucket.web.example.com, если DNS и reverse-proxy для него настроены (следующий раздел).
Reverse-proxy и TLS перед Garage
Garage сам не занимается TLS — эту работу отдают reverse-proxy. Проще всего — Caddy с автоматическим Let's Encrypt, особенно если у вас уже есть готовая инструкция по установке Caddy с авто-SSL на VPS:
# Caddyfile
s3.example.com {
reverse_proxy 127.0.0.1:3900
}
*.s3.example.com {
reverse_proxy 127.0.0.1:3900
}
*.web.example.com {
reverse_proxy 127.0.0.1:3902
}
Wildcard-поддомены нужны, если вы используете virtual-hosted-style обращение к бакетам через поддомены (root_domain в конфиге) — для wildcard-сертификата Caddy потребуется DNS-01 challenge с API-ключом вашего DNS-провайдера через модуль caddy-dns.
На Nginx схема аналогичная — терминируете TLS на 443 и проксируете на 127.0.0.1:3900, не забыв про заголовки для больших PUT-запросов:
server {
listen 443 ssl;
server_name s3.example.com *.s3.example.com;
client_max_body_size 5G;
proxy_buffering off;
location / {
proxy_pass http://127.0.0.1:3900;
proxy_set_header Host $host;
}
}
Подробности — в статье про настройку Nginx как reverse-proxy на VPS. Если у кластера три узла в разных локациях, логичнее ставить reverse-proxy с TLS перед каждым отдельно и балансировать клиентов через DNS — так пропадает единая точка отказа не только на уровне хранилища, но и прокси.
Мониторинг, бэкап и типичные проблемы
Garage отдаёт метрики в формате Prometheus через admin API (GET /metrics на admin.api_bind_addr) — подключить их к уже поднятому стеку Grafana + Prometheus не сложнее любого другого exporter'а: job в prometheus.yml с целью 127.0.0.1:3903.
Бэкап — это каталоги metadata_dir и data_dir на каждом узле плюс garage.toml. Данные уже реплицированы между зонами, поэтому для восстановления узла обычно достаточно поднять новый VPS и завести его в layout. Но это не заменяет бэкап на случай логической ошибки (удаление бакета сотрёт копии сразу во всех зонах) — проще всего гонять rclone sync из бакета Garage во внешнее хранилище по расписанию, как в статье про бэкап и восстановление MinIO, только источник — эндпоинт Garage.
Частые проблемы на старте:
- Узлы не видят друг друга в
garage status— разныйrpc_secretили закрыт порт 3901. Сверьте секрет и проверьтеnc -zv <ip> 3901. layout applyзавис, данные не перебалансируются — обычно медленная сеть между зонами при большом объёме. Смотритеgarage statsи дождитесь.- S3-клиент получает 403 — неверные ключи или бакет не разрешён для ключа. Проверьте
garage bucket infoиgarage key info.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем Garage принципиально проще MinIO для новичка?
Меньше настроек по умолчанию — кластер описывается одним TOML на узел плюс несколько CLI-команд для layout. Обратная сторона — меньше готовых интеграций и зрелой документации на русском.
Можно ли начать с одного VPS и потом дорастить до геокластера?
Да: поднимаете узел с replication_factor = 1 для теста, а когда готовы — меняете фактор и добавляете узлы через layout assign. Если кластер задуман геораспределённым, лучше сразу планировать фактор на 3.
Нужен ли SSD или подойдёт HDD?
Для метаданных (LMDB/SQLite) желателен SSD — от него зависит латентность операций. Для самих объектов подойдёт и более медленный диск при нетребовательной к IOPS нагрузке.
Как перенести данные с MinIO на Garage?
Через rclone — два remote (minio и garage) и rclone sync minio:bucket garage:bucket. Оба совместимы с S3 API, но лучше прогнать sync дважды, чтобы забрать файлы, записанные уже во время первого прогона.
Что будет, если один из трёх узлов в другой стране надолго ляжет?
При replication_factor = 3 кластер продолжит работать с оставшихся двух — записи временно будут иметь меньше копий, но не потеряются. Garage довосстановит нужное число, когда узел вернётся или будет заменён в layout.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →