RustFS - Установка и настройка S3-совместимого хранилища
Приветствую!

В этой статье рассмотрим установку и базовую настройку RustFS - S3-совместимого объектного хранилища, которое будем поднимать на Linux сервере с помощью Docker Compose.

Задача: получить свой S3-endpoint, веб-консоль, валидное HTTPS подключение (через Caddy + Let’s Encrypt) и проверить, что всё это добро работает с помощью замечательных утилит rclone и restic 😌.

Вводные данные

Для настройки нашей инсталляции подразумевается, что у нас уже есть 📃:

Установка S3-хранилища RustFS

Подключаемся к серверу rustfs.r4ven.me с помощью SSH и переходим на УЗ root с помощью sudo:

BASH
ssh ivan@rustfs.r4ven.me

sudo -i
Нажмите, чтобы развернуть и увидеть больше

Создаём директорию проекта и ограничиваем доступ к ней с помощью команды chmod:

BASH
mkdir -vp /etc/compose/rustfs && cd /etc/compose/rustfs

chmod 700 /etc/compose
Нажмите, чтобы развернуть и увидеть больше

Теперь создаём compose-файл, например, с помощью редактора vim:

BASH
vim ./compose.yaml
Нажмите, чтобы развернуть и увидеть больше

Наполняем:

YAML
---
# https://github.com/rustfs/rustfs
# https://caddyserver.com/docs/running#docker-compose

volumes:
  rustfs:
    name: rustfs
  caddy:
    name: caddy

services:
  rustfs:
    image: docker.io/rustfs/rustfs:1.0.0-beta.8
    container_name: rustfs
    restart: unless-stopped
    stop_grace_period: 30s
    cpus: 1
    mem_limit: 1G
    hostname: rustfs
    user: "root:root"
    env_file: ./.env
    healthcheck:
      test:
        ["CMD", "sh", "-c", "curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9001/rustfs/console/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    expose:
      - "9000" # S3 API port
      - "9001" # Console port
    volumes:
      - rustfs:/data/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

  caddy:
    image: docker.io/caddy:2.9.1-alpine
    depends_on:
      rustfs:
        condition: service_healthy
    container_name: caddy
    restart: unless-stopped
    stop_grace_period: 30s
    cpus: 1
    mem_limit: 512M
    hostname: caddy
    env_file: ./.env
    environment:
      TZ: Europe/Moscow
    configs:
      - source: caddy_config
        target: /etc/caddy/Caddyfile
    command: caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
    healthcheck:
      test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider https://${RUSTFS_DOMAIN}:443/health && wget --no-verbose --tries=1 --spider https://${RUSTFS_CONSOLE_DOMAIN}:443/rustfs/console/auth/login"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    ports:
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
    volumes:
      - caddy:/data/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

configs:
  caddy_config:
    content: |
      {
          email ${ACME_EMAIL}
          admin off
      }

      ${RUSTFS_DOMAIN} {
          reverse_proxy rustfs:9000

          header {
              Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
              X-Content-Type-Options "nosniff"
              X-Frame-Options "DENY"
              Referrer-Policy "no-referrer"
          }
      }

      ${RUSTFS_CONSOLE_DOMAIN} {
          reverse_proxy rustfs:9001

          header {
              Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
              X-Content-Type-Options "nosniff"
              X-Frame-Options "DENY"
              Referrer-Policy "no-referrer"
          }
      }
Нажмите, чтобы развернуть и увидеть больше

Данный файл описывает два сервиса: rustfs и caddy. Если с первым всё понятно, то про второй стоит немного добавить информации.

Теперь создаём env файл:

BASH
vim ./.env
Нажмите, чтобы развернуть и увидеть больше

Наполняем:

INI
# https://docs.rustfs.com/installation/docker/#complete-parameter-configuration-example

TZ=Europe/Moscow

ACME_EMAIL=kar-kar@r4ven.me
RUSTFS_DOMAIN=rustfs.r4ven.me
RUSTFS_CONSOLE_DOMAIN=rustfs-console.r4ven.me

# RUSTFS_UID="root"
# RUSTFS_GID="root"
# RUSTFS_VOLUMES=/data/rustfs{0..3} # Define 4 storage volumes
RUSTFS_ADDRESS=0.0.0.0:9000
RUSTFS_CONSOLE_ENABLE=true
RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
RUSTFS_CORS_ALLOWED_ORIGINS=https://rustfs-console.r4ven.me
RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=https://rustfs-console.r4ven.me
RUSTFS_ACCESS_KEY=
RUSTFS_SECRET_KEY=
RUSTFS_OBS_LOGGER_LEVEL=info
Нажмите, чтобы развернуть и увидеть больше

Caddyfile отдельным файлом не создаём. Docker Compose передаёт его в контейнер через параметр configs, а переменные окружения подставляет при обработке compose-файла. Сертификаты Let’s Encrypt и прочие файлы Caddy будет хранит в docker volume с названием caddy.

Задаём “логин” и генерируем “пароль”:

BASH
sed -iE "s/^RUSTFS_ACCESS_KEY=.*/RUSTFS_ACCESS_KEY=ivan/" ./.env

sed -iE "s/^RUSTFS_SECRET_KEY=.*/RUSTFS_SECRET_KEY=$(openssl rand -hex 32)/" ./.env
Нажмите, чтобы развернуть и увидеть больше

Теперь запускаем стек:

BASH
docker compose up -d && docker compose logs -f
Нажмите, чтобы развернуть и увидеть больше

Проверяем:

BASH
docker compose ps

docker volume ls | grep -E "rustfs|caddy"

ls -lR /var/lib/docker/volumes/caddy/_data/caddy/
Нажмите, чтобы развернуть и увидеть больше

Сразу же настроим автозапуск с помощью Systemd:

BASH
cat > ./rustfs.service << EOF
[Unit]
Description=RustFS S3 service
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/etc/compose/rustfs
ExecStart=/usr/bin/docker compose up --remove-orphans
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
EOF
Нажмите, чтобы развернуть и увидеть больше
BASH
chmod 600 ./rustfs.service

ln -s $(realpath ./rustfs.service) /etc/systemd/system

systemctl daemon-reload

systemctl enable --now rustfs

systemctl status rustfs
Нажмите, чтобы развернуть и увидеть больше

Теперь сервисом rustfs можно управлять утилитой systemctl:

BASH
systemctl stop rustfs
systemctl start rustfs
systemctl restart rustfs
systemctl status rustfs
Нажмите, чтобы развернуть и увидеть больше

Настройка RustFS

Открываем веб-браузер и вводим адрес:

BASH
https://rustfs-console.r4ven.me
Нажмите, чтобы развернуть и увидеть больше

Увидим окно входа в консоль управления S3-хранилища. Обратите внимание на защищённое соединение:

Для входа используйте данные, которые мы сгенерировали шагом ранее:

BASH
grep -E 'RUSTFS_ACCESS_KEY|RUSTFS_SECRET_KEY' /etc/compose/rustfs/.env
Нажмите, чтобы развернуть и увидеть больше

Создание бакетов

Ниже покажу процесс создания бакетов:

На вкладке “Браузер” нажимаем “Создать бакет”:

Во всплывающем окне задаём ему имя, например, app1, устанавливаем квоту (ограничение размера хранилища) и нажимаем “Создать”:

В списке бакетов увидим созданный нами:

Создание реквизитов доступа

Следующим шагом мы создадим реквизиты доступа к бакету для клиентских подключений. Хорошим тоном считается использование отдельной учётной записи для выполнения различных манипуляций с бакетами с помощью API.

Переходим в “Пользователи” –> “Добавить пользователя”:

Тут указываем имя, в нашем примере backup, и задаём ему пароль. В разделе “Политика” выбираем readwrite и жмём “Отправить”:

После создания нажимаем “Редактировать” напротив нового пользователя:

Переходим на вкладку “Ключи доступа” и жмём “Добавить ключи доступа”:

Тут указываем произвольное имя и описание. Также можно установить срок действия ключа. Если дату не выбирать, ключ будет активен бесконечно. Завершаем создание кнопкой “Отправить”:

Появится окно с новым ключом доступа и секретным ключом. Обязательно сохраните их, возможно, даже экспортируйте, т.к. больше их просмотреть будет невозможно:

В нашем примере данные следующие:

Таких ключей для одного пользователя можно создавать большое количество с разными политиками доступа.

Проверка работы S3 с помощью Rclone

Для тестирования работы нашего объектного хранилища воспользуемся замечательной утилитой - rclone, по которой я недавно делал статью про монтирование удалённых хранилищ.

Утилита доступна в стандартных репозиториях Linux. Выполняем установку и создаём конфиг с помощью механизма here doc оболочки. Не забудьте подставить свои значения для endpoint, access_key_id (ключ доступа) и secret_access_key (секретный ключ):

BASH
apt install -y rclone

mkdir -vp ~/.config/rclone

cat > ~/.config/rclone/rclone.conf << EOF
[rustfs]
type = s3
provider = Minio
endpoint = https://rustfs.r4ven.me
access_key_id = haRQaZRE9OGlUULAE2EQ
secret_access_key = QkgSFIG03saT2l7tnIF7OSUuxIwmKlx6RabFOs9i
EOF
Нажмите, чтобы развернуть и увидеть больше

Проверяем доступ к хранилищу:

BASH
rclone lsd rustfs:
Нажмите, чтобы развернуть и увидеть больше

Если увидите название вашего бакета, значит подключение успешно:

Теперь создадим “директорию” внутри бакета и скопируем туда tar архив с содержимым директории /etc с помощью механизма перенаправления потоков:

BASH
tar -czf - /etc | rclone rcat rustfs:app1/rclone/backup_etc_$(date '+%F').tar.gz

rclone ls rustfs:app1/rclone
Нажмите, чтобы развернуть и увидеть больше

Восстановить файлы из S3 с помощью rclone можно так:

BASH
mkdir -vp /tmp/restore/rclone

# Архив одним файлом
rclone copy rustfs:app1/rclone/backup_etc_2026-06-16.tar.gz /tmp/restore/rclone

# Сразу разархивировать
rclone cat rustfs:app1/rclone/backup_etc_2026-06-16.tar.gz | tar -xzf - -C /tmp/restore/rclone

ls -l /tmp/restore/rclone
Нажмите, чтобы развернуть и увидеть больше

Проверка работы S3 с помощью Restic

Другой популярный сценарий использования S3 - резервное копирование с помощью другой замечательной утилиты restic.

restic также доступен в стандартных репозиториях Linux. Способ его конфигурации несколько отличается от того же rclone. Все параметры задаются в переменных окружения, которые необходимо подгружать для каждой терминальной сессии.

Давайте установим restic и сохраним все нужные параметры в файл env, чтобы было удобно их подгружать целиком:

BASH
apt install -y restic

mkdir -vp ~/.config/restic

cat > ~/.config/restic/env << EOF
export AWS_ACCESS_KEY_ID="haRQaZRE9OGlUULAE2EQ"  
export AWS_SECRET_ACCESS_KEY="QkgSFIG03saT2l7tnIF7OSUuxIwmKlx6RabFOs9i"  
export AWS_DEFAULT_REGION="us-east-1"  
export RESTIC_REPOSITORY="s3:https://rustfs.r4ven.me/app1/restic"
export RESTIC_PASSWORD="12345678"
EOF

source ~/.config/restic/env
Нажмите, чтобы развернуть и увидеть больше

Теперь давайте инициализируем репозиторий restic и создадим резервную копию директории /etc, как мы делали ранее с rclone, только уже без tar:

BASH
restic init

restic backup /etc

restic stats

restic snapshots
Нажмите, чтобы развернуть и увидеть больше

Посмотреть содержимое репозитория:

BASH
restic ls latest | less
Нажмите, чтобы развернуть и увидеть больше

Восстановить файлы в указанную директорию из последней резервной копии можно так:

BASH
restic restore latest --target /tmp/restore/restic

ls -l /tmp/restore/restic
Нажмите, чтобы развернуть и увидеть больше

Послесловие

И так, мы с вами настроили собственное S3-совместимое хранилище RustFS, закрытое за обратным прокси Caddy. Для небольшого личного сервера, бэкапов, тестовых бакетов и всяких внутренних сервисов - вполне отличный вариант 👍.

Сам проект RustFS ещё выглядит молодым, поэтому я бы рекомендовал следить за обновлениями и использовать его в проде с чуть большей осторожностью, чем тот же MinIO.

Спасибо, что читаете. И помните, админы делятся на два типа: те, кто делает бэкапы, и тех кто обязательно будет их делать. Всех благ!

Используемые материалы

Авторские права

Автор: Иван Чёрный

Ссылка: https://r4ven.me/storage/rustfs-ustanovka-i-nastroyka-s3-sovmestimogo-hranilishcha/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша