Установка и запуск Garage S3 с docker-compose
Опубликовано:
В данной инструкции мы рассмотрим базовые команды по запуску и настройке Garage S3 в docker. В качестве оркестратора будем использовать docker-compose.
Пример файла docker-compose
Настройка s3 и запуск контейнера
Добавление хранилища
Настройка обратного проксирования
Дополнительные материалы
Файлы docker-compose и .env
Создадим каталог, в котором разместим данные и сразу перейдем в него:
mkdir /opt/s3garage && cd /opt/s3garage
Создаем файл:
vi docker-compose.yml
services:
garage:
image: dxflrs/garage:${GR_VER}
container_name: garage
hostname: garage
restart: unless-stopped
ports:
- ${PORT_API}:${PORT_API}
- ${PORT_RPC}:${PORT_RPC}
- ${PORT_WEB}:${PORT_WEB}
- ${PORT_ADM}:${PORT_ADM}
volumes:
- ./garage/garage.toml:/etc/garage.toml
- ./garage/data:/var/lib/garage
environment:
TZ: ${TIMEZONE}
healthcheck:
test: ["CMD", "/garage", "status"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
Создаем env файл:
vi .env
DOMAIN=s3.dmosk.ru
GR_VER=v2.3.0
TIMEZONE=Europe/Moscow
PORT_API=3900
PORT_RPC=3901
PORT_WEB=3902
PORT_ADM=3903
* где обязательно укажите:
- DOMAIN — ваше доменное имя, на котором будет работать S3.
- GR_VER — актуальную версию Garage. Сверьтесь с Docker Hub.
- TIMEZONE — временную зону региона, где расположен сервер.
Основные файлы контейнеризации готовы. Перейдем к настройке приложения и его запуску.
Настройка и запуск
Чтобы приложение запустилось, необходимо заранее создать конфигурационный файл garage. Разместим его в каталоге garage:
mkdir garage
Читаем переменные из созданного ранее файла env:
source .env
Создаем конфигурационный файл для garage:
cat > ./garage/garage.toml <<EOF
metadata_dir = "/var/lib/garage/meta"
data_dir = "/var/lib/garage/data"
db_engine = "sqlite"
replication_factor = 1
rpc_bind_addr = "[::]:${PORT_RPC}"
rpc_public_addr = "127.0.0.1:${PORT_RPC}"
rpc_secret = "$(openssl rand -hex 32)"
[s3_api]
s3_region = "garage"
api_bind_addr = "[::]:${PORT_API}"
[s3_web]
bind_addr = "[::]:${PORT_WEB}"
root_domain = ".${DOMAIN}"
index = "index.html"
[admin]
api_bind_addr = "[::]:${PORT_ADM}"
admin_token = "$(openssl rand -base64 32)"
metrics_token = "$(openssl rand -base64 32)"
EOF
Приложение готово к запуску.
Выполняем команду:
docker-compose up -d
Проверяем статус:
docker exec garage /garage status
Мы должны увидеть что-то на подобие:
2026-04-17T20:56:22.531331Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T20:56:22.573328Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== HEALTHY NODES ====
ID Hostname Address Tags Zone Capacity DataAvail Version
23bd594a7ecc3adb garage 127.0.0.1:3901 NO ROLE ASSIGNED v2.3.0
Обратите внимание на последовательность, выделенную желтым. Это идентификатор запущенного экземпляра S3. Фиксируем его — он потребуется при дальнейшей настройке.
Создание бакета и настройка прав
Мы запустили приложение, но оно не будет полноценно работать, пока мы не создадим бакет и не дадим к нему доступ.
Для нашего удобства мы создадим переменные:
ID=23bd594a7ecc3adb
KEY_NAME=key1
BUCKET_NAME=bucket1
* где:
- ID — идентификатор запущенного S3, который мы получили на предыдущем этапе.
- KEY_NAME — имя ключа доступа. Лучше задать что-то, что потом проще будет идентифицировать.
- BUCKET_NAME — имя бакета. Также лучше задать понятное имя.
Задаем дисковую емкость (10 ГБ) и логическое расположение в зоне local:
docker exec garage /garage layout assign ${ID} -c 10G -z local
* вместо 10G укажите свой лимит на использование дискового ресурса.
Мы должны увидеть что-то такое:
2026-04-17T21:12:29.834441Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:12:29.876493Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
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.
Применяем настройки:
docker exec garage /garage layout apply --version 1
Мы должны увидеть что-то на подобие:
2026-04-17T21:13:15.820540Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:13:15.862400Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== COMPUTATION OF A NEW PARTITION ASSIGNATION ====
Partitions are replicated 1 times on at least 1 distinct zones.
Optimal partition size: 39.1 MB
Usable capacity / total cluster capacity: 10.0 GB / 10.0 GB (100.0 %)
Effective capacity (replication factor 1): 10.0 GB
local Tags Partitions Capacity Usable capacity
23bd594a7ecc3adb [] 256 (256 new) 10.0 GB 10.0 GB (100.0%)
TOTAL 256 (256 unique) 10.0 GB 10.0 GB (100.0%)
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 key create ${KEY_NAME}
На консоли отобразятся данные аутентификации на S3:
2026-04-17T21:18:08.752091Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:18:08.794417Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== ACCESS KEY INFORMATION ====
Key ID: GK54f3fb88d157b66a5f53b92f
Key name: key1
Secret key: 9200b62997df1c97e86557d01b287892d6c26f1acaf71b599db3130322175d79
Created: 2026-04-17 21:18:08.794 +00:00
Validity: valid
Expiration: never
Can create buckets: false
==== BUCKETS FOR THIS KEY ====
Permissions ID Global aliases Local aliases
* где для нас важны:
- Key ID — Access Key ID (или просто Access Key / Логин).
- Secret key — Secret Access Key (или Secret Key / Пароль).
Создаем бакет:
docker exec garage /garage bucket create ${BUCKET_NAME}
Мы увидим информацию о созданном объектном хранилище:
2026-04-17T21:22:30.767014Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:22:30.809379Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== BUCKET INFORMATION ====
Bucket: 063670204081a166c10b9e286adcf84c9719cd3146a0c3746252783f9c1fb3bb
Created: 2026-04-17 21:22:30.810 +00:00
Size: 0 B (0 B)
Objects: 0
Website access: false
Global alias: bucket1
==== KEYS FOR THIS BUCKET ====
Permissions Access key Local aliases
Теперь предоставим доступ созданному ключу к созданному S3-бакету:
docker exec garage /garage bucket allow ${BUCKET_NAME} --read --write --key ${KEY_NAME}
Мы опять увидим информацию о хранилище, но в нижней части в доступах будет указан ключ:
2026-04-17T21:23:16.731613Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:23:16.773464Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== BUCKET INFORMATION ====
Bucket: 063670204081a166c10b9e286adcf84c9719cd3146a0c3746252783f9c1fb3bb
Created: 2026-04-17 21:22:30.810 +00:00
Size: 0 B (0 B)
Objects: 0
Website access: false
Global alias: bucket1
==== KEYS FOR THIS BUCKET ====
Permissions Access key Local aliases
RW GK54f3fb88d157b66a5f53b92f key1
Хранилище готово к использованию. Мы выделили пространство, создали бакет и дали к нему доступ.
Посмотреть общее состояние Garage и получить список дисковых емкостей можно командой:
docker exec garage /garage status
Мы должны увидеть что-то на подобие:
2026-04-17T21:26:49.361546Z INFO garage_net::netapp: Connected to 127.0.0.1:3901, negotiating handshake...
2026-04-17T21:26:49.403409Z INFO garage_net::netapp: Connection established to 23bd594a7ecc3adb
==== HEALTHY NODES ====
ID Hostname Address Tags Zone Capacity DataAvail Version
23bd594a7ecc3adb garage 127.0.0.1:3901 [] local 10.0 GB 32.5 GB (63.9%) v2.3.0
Посмотреть информацию о бакете можно командой:
docker exec garage /garage bucket info ${BUCKET_NAME}
Мы можем пробовать подключиться к настроенному S3. Пример настроек, которые нужно указать в приложении для подключения:
- API URL (Endpoint): https://s3.dmosk.ru:3900
- Key ID (Access Key): GK54f3fb88d157b66a5f53b92f
- Secret key (Secret Key): 9200b62997df1c97e86557d01b287892d6c26f1acaf71b599db3130322175d79
- Region: garage
- Path style: path
- Security: без шифрования
Замените значения пути и ключей на свои. В качестве приложения для проверки можно использовать S3 Browser или WinSCP.
Обратное проксирование
Дополнительно рассмотрим небольшие примеры по настройке веб-серверов в качестве обратного прокси. Это поможет легко настроить SSL шифрование, а также сделать имена подключения более красивыми. Также, с точки зрения безопасности, данный подход позволит не открывать прямой сетевой доступ к серверу S3.
При этом, мы рассмотрим NGINX, в качестве внешнего прокси (который вынесен за пределы сервера s3) и Caddy, в качестве веб-сервера, развернутого в контейнере в том же docker-compose, котором запускался сам garage.
NGINX
Пример location для конфигурирования nginx в качестве обратного прокси для garage s3:
location / {
proxy_pass http://192.168.1.10:3900/;
proxy_redirect off;
proxy_http_version 1.1;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
* где 192.168.1.10 — IP-адрес сервера s3, который доступен с nginx. Также обратите внимание, что в данном примере используется корневой location. Вы, возможно, захотите использовать /s3/ или что-то подобное.
После внесения настройки не забываем перезапустить nginx:
nginx -t && nginx -s reload
Caddy
Теперь рассмотрим обратный прокси, который будет запускаться тем же docker-compose, который мы сделали для garage:
vi docker-compose.yml
Удаляем ports из garage и добавляем новый сервис caddy:
garage:
...
ports:
- ${PORT_API}:${PORT_API}
- ${PORT_RPC}:${PORT_RPC}
- ${PORT_WEB}:${PORT_WEB}
- ${PORT_ADM}:${PORT_ADM}
...
caddy:
image: caddy:2.11
hostname: caddy
container_name: caddy
restart: unless-stopped
environment:
TZ: ${TIMEZONE}
DOMAIN: ${DOMAIN}
ports:
- 80:80
- 443:443
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
Создаем каталог для caddy:
mkdir caddy
А также создаем конфигурационный файл:
vi caddy/Caddyfile
{$DOMAIN} {
handle {
reverse_proxy garage:3900
}
}
Запускаем контейнеры:
docker-compose up -d
Пробуем подключиться к s3. Теперь в качестве эндпоинта можно использовать https подключения по доменному имени и без указания порта. В нашем примере, https://s3.dmosk.ru.
Читайте также
Другие полезные материалы:
2. Создание собственного образа Docker.