Установка и запуск Garage S3 с docker-compose

Обновлено и опубликовано Опубликовано:

В данной инструкции мы рассмотрим базовые команды по запуску и настройке Garage S3 в docker. В качестве оркестратора будем использовать docker-compose.

Файлы 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.

Читайте также

Другие полезные материалы:

1. Установка Docker на Linux.

2. Создание собственного образа Docker.

3. Шпаргалка для docker healthcheck.

4. Шпаргалка по работе с docker-compose.

# DevOps # Linux # Контейнеризация # Серверы
Дмитрий Моск — частный мастер
Был ли вам полезен этот скрипт?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Заказать настройку контейнеризации

Нужна бесплатная консультация?

Скрипты

Пример файла docker-compose для запуска Garage S3

Сценарий в docker-compose для запуска Rocket.Chat

Запуск Nextcloud с помощью docker-compose со всем необходимым

Пример скрипта на Python для копирования пакетов NPM с одного репозитория Nexus в другой

Развертывание caddy прокси в docker с помощью docker-compose

Файл docker-compose для развертывания Nginx Proxy Manager

Пример файла docker-compose для запуска контейнеров с сервером Grafana Loki

Другие скрипты

Все статьи

Нужен скрипт? Опишите его назначение:





Реклама