В этой статье рассмотрим установку и базовую настройку RustFS - S3-совместимого объектного хранилища, которое будем поднимать на Linux сервере с помощью Docker Compose.
Задача: получить свой S3-endpoint, веб-консоль, валидное HTTPS подключение (через Caddy + Let’s Encrypt) и проверить, что всё это добро работает с помощью замечательных утилит rclone и restic 😌.
📝 К слову, RustFS позиционируется разработчиками как альтернатива печально известному MinIO.
🖐️Эй!
Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике — заглядывайте в Вороний чат @r4ven_me_chat🧐.
Вводные данные
Для настройки нашей инсталляции подразумевается, что у нас уже есть 📃:
- Linux сервер на базе Debian 13, доступный по белому IP из интернета;
- Установленный Docker Engine на этом Linux сервере;
- Домены типа
rustfs.r4ven.meиrustfs-console.r4ven.me, указывающие на белый IP адрес нашего сервера; - Привилегированный доступ к системе.
Установка S3-хранилища RustFS

Подключаемся к серверу rustfs.r4ven.me с помощью SSH и переходим на УЗ root с помощью sudo:
ssh ivan@rustfs.r4ven.me
sudo -i📝 Примечание
В этот раз файлы проекта мы будем хранить по пути /etc/compose. А данные приложения в Docker volume.
Создаём директорию проекта и ограничиваем доступ к ней с помощью команды chmod:
mkdir -vp /etc/compose/rustfs && cd /etc/compose/rustfs
chmod 700 /etc/composeТеперь создаём compose-файл, например, с помощью редактора vim:
vim ./compose.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. Если с первым всё понятно, то про второй стоит немного добавить информации.
📝 Caddy - это современный веб-сервер и обратный прокси с автоматическим получением и продлением TLS-сертификатов, простой декларативной конфигурацией и встроенной поддержкой HTTP/2, HTTP/3, балансировки нагрузки, проксирования и статического контента. Часто используется как более простой в настройке аналог Nginx, особенно в небольших и средних инфраструктурах.
Теперь создаём env файл:
vim ./.envНаполняем:
# 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☝️ Значения из переменных RUSTFS_ACCESS_KEY и RUSTFS_SECRET_KEY будут использоваться как логин и пароль для авторизации в веб-консоли RustFS.
Caddyfile отдельным файлом не создаём. Docker Compose передаёт его в контейнер через параметр configs, а переменные окружения подставляет при обработке compose-файла. Сертификаты Let’s Encrypt и прочие файлы Caddy будет хранит в docker volume с названием caddy.
☝️ Как уже говорил, для выпуска сертификатов DNS записи определенные в RUSTFS_DOMAIN и RUSTFS_CONSOLE_DOMAIN должны указывать на адрес вашего сервера, а порты 80/tcp и 443/tcp должны быть доступны снаружи.
Задаём “логин” и генерируем “пароль”:
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Теперь запускаем стек:
docker compose up -d && docker compose logs -fПроверяем:
docker compose ps
docker volume ls | grep -E "rustfs|caddy"
ls -lR /var/lib/docker/volumes/caddy/_data/caddy/Сразу же настроим автозапуск с помощью Systemd:
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
EOFchmod 600 ./rustfs.service
ln -s $(realpath ./rustfs.service) /etc/systemd/system
systemctl daemon-reload
systemctl enable --now rustfs
systemctl status rustfsТеперь сервисом rustfs можно управлять утилитой systemctl:
systemctl stop rustfs
systemctl start rustfs
systemctl restart rustfs
systemctl status rustfsНастройка RustFS
Открываем веб-браузер и вводим адрес:
https://rustfs-console.r4ven.meУвидим окно входа в консоль управления S3-хранилища. Обратите внимание на защищённое соединение:

Для входа используйте данные, которые мы сгенерировали шагом ранее:
grep -E 'RUSTFS_ACCESS_KEY|RUSTFS_SECRET_KEY' /etc/compose/rustfs/.envСоздание бакетов
Ниже покажу процесс создания бакетов:
📝 Примечание
Bucket в S3 - это как контейнер для “файлов”. Аналог папки верхнего уровня, в которой хранятся объекты (файлы) и настраиваются права доступа, версии и политики хранения. Имя бакета задаётся произвольное, например, бакет backups.
На вкладке “Браузер” нажимаем “Создать бакет”:
Во всплывающем окне задаём ему имя, например, app1, устанавливаем квоту (ограничение размера хранилища) и нажимаем “Создать”:

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

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

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

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

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

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

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

В нашем примере данные следующие:
- Ключ доступа:
haRQaZRE9OGlUULAE2EQ - Секретный ключ:
QkgSFIG03saT2l7tnIF7OSUuxIwmKlx6RabFOs9i
Таких ключей для одного пользователя можно создавать большое количество с разными политиками доступа.
Проверка работы S3 с помощью Rclone

Для тестирования работы нашего объектного хранилища воспользуемся замечательной утилитой - rclone, по которой я недавно делал статью про монтирование удалённых хранилищ.
📝 Примечание
rclone - это консольная утилита для работы с облачными и S3-совместимыми хранилищами. Позволяет копировать, синхронизировать, монтировать и управлять файлами между локальной системой и удалёнными хранилищами (S3, MinIO, RustFS, Google Drive, OneDrive и десятками других сервисов). Часто используется как аналог rsync для облачных хранилищ.
Утилита доступна в стандартных репозиториях Linux. Выполняем установку и создаём конфиг с помощью механизма here doc оболочки. Не забудьте подставить свои значения для endpoint, access_key_id (ключ доступа) и secret_access_key (секретный ключ):
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Проверяем доступ к хранилищу:
rclone lsd rustfs:Если увидите название вашего бакета, значит подключение успешно:

Теперь создадим “директорию” внутри бакета и скопируем туда tar архив с содержимым директории /etc с помощью механизма перенаправления потоков:
tar -czf - /etc | rclone rcat rustfs:app1/rclone/backup_etc_$(date '+%F').tar.gz
rclone ls rustfs:app1/rclone
💡 Узнать список доступных команд, как обычно, можно с помощью rclone --help.
📝 Примечание
Почему tar архив а не прямое копирование файлов в S3? Дело в том, что обычное копирование с помощью rclone плохо работает с символическими ссылками. Поэтому чаще всего в связке с ним используют наш любимый архиватор tar.
Восстановить файлы из S3 с помощью rclone можно так:
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 - это консольная программа для резервного копирования, которая создаёт дедуплицированные, зашифрованные и версионированные бэкапы файлов и каталогов. Может хранить резервные копии локально, по SFTP или в S3-совместимых хранилищах (например, MinIO или RustFS), позволяя восстанавливать данные на любой момент времени из сохранённых снимков (snapshots).
restic также доступен в стандартных репозиториях Linux. Способ его конфигурации несколько отличается от того же rclone. Все параметры задаются в переменных окружения, которые необходимо подгружать для каждой терминальной сессии.
Давайте установим restic и сохраним все нужные параметры в файл env, чтобы было удобно их подгружать целиком:
☝️ Не забудьте подставить свои значения.
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_PASSWORD указывается пароль, с помощью которого файлы в репозитории restic будут зашифрованы.
💡 Совет
При необходимости, вы можете добавить экспорт данных переменных в ваше окружение через *rc файл вашей оболочки. Пример для Bash:
echo 'source ~/.config/restic/env' >> ~/.bashrcТеперь давайте инициализируем репозиторий restic и создадим резервную копию директории /etc, как мы делали ранее с rclone, только уже без tar:
restic init
restic backup /etc
restic stats
restic snapshots
Посмотреть содержимое репозитория:
restic ls latest | less
Восстановить файлы в указанную директорию из последней резервной копии можно так:
restic restore latest --target /tmp/restore/restic
ls -l /tmp/restore/restic
Послесловие
И так, мы с вами настроили собственное S3-совместимое хранилище RustFS, закрытое за обратным прокси Caddy. Для небольшого личного сервера, бэкапов, тестовых бакетов и всяких внутренних сервисов - вполне отличный вариант 👍.
Сам проект RustFS ещё выглядит молодым, поэтому я бы рекомендовал следить за обновлениями и использовать его в проде с чуть большей осторожностью, чем тот же MinIO.
Спасибо, что читаете. И помните, админы делятся на два типа: те, кто делает бэкапы, и тех кто обязательно будет их делать. Всех благ!


