MAATRIX / Блог / MinIO на Ubuntu 24.04: пошаговая установка

MinIO на Ubuntu 24.04: пошаговая установка

MAATRIX

Если приложение хранит файлы — аватарки, бэкапы, видео, артефакты сборки — рано или поздно диск сервера заканчивается или файлы нужно раздавать через CDN. Держать их на AWS S3 — это доллары и задержка до зарубежного региона, а просто складывать в папку на диске — значит вручную решать вопросы версионирования, прав доступа и API. MinIO закрывает эту нишу: он поднимает на вашем сервере хранилище, полностью совместимое по протоколу с Amazon S3, и любой SDK или CLI, написанный под S3, будет работать с ним без изменений.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое MinIO и когда он нужен

MinIO — это объектное хранилище с открытым кодом, которое говорит на том же языке, что и S3: те же вызовы API (PutObject, GetObject, ListBucket), та же модель бакетов и политик доступа, та же поддержка presigned URL. Разница в том, что MinIO развернут у вас, вы платите только за сервер и трафик, а данные физически находятся там, где вы решили — в РФ, США или Европе, в зависимости от того, где арендован сервер.

Типичные сценарии использования:

  • бэкенд для загрузки пользовательских файлов (документы, изображения, видео);
  • хранилище артефактов CI/CD — Docker-слои, собранные пакеты, дистрибутивы;
  • приёмник резервных копий с других серверов через mc mirror или rclone;
  • локальный кэш перед раздачей через CDN или как origin для Nginx.

Важная оговорка: этот гайд разворачивает single-node single-drive конфигурацию — один сервер, один диск с данными. Она отлично подходит для старта, разработки и большинства проектов среднего размера, но не даёт отказоустойчивости на уровне диска: если диск умрёт, данные пропадут, если их не бэкапить отдельно. Для продакшена с требованиями к надёжности MinIO рекомендует erasure coding на 4+ дисках или нескольких узлах — об этом ниже, в разделе про бэкапы.

Под задачу нужен сервер с достаточным объёмом диска под данные — для файлового хранилища это часто не про CPU и RAM, а именно про дисковое пространство и скорость сети.

Подготовка сервера и установка бинарника

Понадобится Ubuntu 24.04 с правами root или sudo, минимум 2 ГБ RAM (для реальной нагрузки — 4 ГБ и больше) и отдельный раздел или диск под данные, если планируете расти. Обновите систему и поставьте базовые утилиты:

apt update && apt upgrade -y
apt install -y wget curl

MinIO не идёт пакетом в стандартных репозиториях Ubuntu — ставим официальный бинарник напрямую с сайта проекта:

wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
chmod +x /usr/local/bin/minio

Проверьте, что бинарник рабочий:

/usr/local/bin/minio --version

Если сервер на ARM (например, некоторые облачные тарифы или Apple Silicon хосты), замените linux-amd64 на linux-arm64 в ссылке.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Systemd-сервис, отдельный пользователь и диск для данных

Запускать MinIO от root — плохая идея: при компрометации сервиса злоумышленник получит полный доступ к системе. Создаём отдельного системного пользователя без домашней директории и шелла:

groupadd -r minio-user
useradd -M -r -g minio-user minio-user

Каталог для данных — если у вас отдельный диск, смонтируйте его сюда; если нет, обычная папка на корневом разделе тоже подойдёт:

mkdir -p /mnt/minio-data
chown minio-user:minio-user /mnt/minio-data

Файл с переменными окружения — здесь задаются логин, пароль и путь к данным:

mkdir -p /etc/minio
cat > /etc/minio/minio.env << 'EOF'
MINIO_ROOT_USER=admin_minio
MINIO_ROOT_PASSWORD=ЗамениНаДлинныйСлучайныйПароль32симв
MINIO_VOLUMES="/mnt/minio-data"
MINIO_OPTS="--address :9000 --console-address :9001"
EOF
chown root:minio-user /etc/minio/minio.env
chmod 640 /etc/minio/minio.env

Сгенерировать нормальный пароль можно так: openssl rand -base64 24. Не оставляйте дефолтные учётные данные — порт 9000 рано или поздно найдут сканеры.

Юнит для systemd:

cat > /etc/systemd/system/minio.service << 'EOF'
[Unit]
Description=MinIO Object Storage
After=network-online.target
Wants=network-online.target

[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/minio/minio.env
ExecStart=/usr/local/bin/minio server $MINIO_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

Запускаем и включаем автостарт:

systemctl daemon-reload
systemctl enable --now minio
systemctl status minio

Порт 9000 — это S3 API, 9001 — веб-консоль администрирования. На этом этапе оба порта открыты только локально по умолчанию сервисом, но фактически слушают на всех интерфейсах — обязательно настройте файрвол, прежде чем открывать их наружу. Если ещё не разворачивали UFW на этом сервере, у нас есть отдельный разбор настройки файрвола с нуля — там же объясняется логика открытия портов по сервисам.

HTTPS-доступ через Nginx как reverse-proxy

Ходить на MinIO напрямую по IP и HTTP небезопасно — логин и пароль от консоли будут идти в открытом виде, а браузер откажется работать с некоторыми API-фичами без TLS. Правильный путь — повесить перед MinIO Nginx с сертификатом Let's Encrypt и завести два поддомена: один для API (s3.example.com), другой для консоли (console.example.com). Использование одного домена с разными путями для API и консоли официально не поддерживается MinIO из-за особенностей маршрутизации — не экономьте здесь, заведите два DNS-имени. Если домен ещё не привязан к серверу, сначала пройдите настройку домена и DNS с нуля.

Если Nginx ещё не установлен как reverse-proxy на этом сервере, у нас есть подробный разбор Nginx как reverse-proxy — установите его по этой инструкции, а затем добавьте конфиги ниже.

Конфиг для S3 API (/etc/nginx/sites-available/s3.example.com):

server {
    listen 80;
    server_name s3.example.com;

    client_max_body_size 0;
    ignore_invalid_headers off;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header Host $host;
        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 $scheme;
        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;
        chunked_transfer_encoding off;
    }
}

Конфиг для консоли (/etc/nginx/sites-available/console.example.com):

server {
    listen 80;
    server_name console.example.com;

    location / {
        proxy_pass http://127.0.0.1:9001;
        proxy_set_header Host $host;
        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 $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

client_max_body_size 0 в первом конфиге снимает лимит Nginx на размер загружаемого объекта — без этого большие файлы будут обрываться ошибкой 413. Активируйте сайты и выпустите сертификаты:

ln -s /etc/nginx/sites-available/s3.example.com /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/console.example.com /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

apt install -y certbot python3-certbot-nginx
certbot --nginx -d s3.example.com -d console.example.com

После выпуска сертификатов certbot сам пропишет listen 443 ssl и редирект с 80 на 443. Порты 9000 и 9001 теперь закройте для внешнего доступа в UFW, оставив их доступными только с localhost — наружу должен смотреть только Nginx на 443.

Клиент mc, бакеты и политики доступа

mc — официальный CLI-клиент MinIO, аналог aws s3 из AWS CLI, но заточенный под MinIO и заметно проще в настройке. Ставится тоже отдельным бинарником:

wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc
chmod +x /usr/local/bin/mc

Подключаем алиас к вашему серверу (можно делать как с самого сервера через localhost, так и с локального компьютера через домен):

mc alias set myminio https://s3.example.com admin_minio ЗамениНаДлинныйСлучайныйПароль32симв
mc admin info myminio

Создаём бакет и проверяем загрузку файла:

mc mb myminio/app-uploads
echo "test" > /tmp/test.txt
mc cp /tmp/test.txt myminio/app-uploads/
mc ls myminio/app-uploads/

По умолчанию бакет приватный — доступ только с валидными ключами. Если нужно отдавать файлы напрямую по ссылке (например, публичные картинки), сделайте только конкретный бакет или префикс публичным для чтения, не открывая весь сервер:

mc anonymous set download myminio/app-uploads

Для приложений заводите отдельных пользователей с ограниченными правами вместо того, чтобы прописывать root-ключи в коде:

mc admin user add myminio app-service ДругойСлучайныйПароль
mc admin policy attach myminio readwrite --user app-service

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

Резервное копирование, мониторинг и обновление

Single-node single-drive конфигурация не защищает от отказа диска — это надо решать отдельно, одним из двух способов:

  1. Зеркалирование на другое хранилище. mc mirror умеет синхронизировать бакеты между двумя MinIO-инстансами или между MinIO и настоящим S3, в том числе инкрементально:
mc alias set backup-target https://backup.example.com admin_minio ПарольВторогоСервера
mc mirror --watch myminio/app-uploads backup-target/app-uploads-backup

Флаг --watch держит процесс запущенным и досылает изменения в реальном времени — удобно вынести в systemd-сервис или в screen/tmux на постоянку.

  1. Снапшоты диска на уровне хостинга или обычный rsync/restic каталога данных на резервный сервер по расписанию. Если на сервере уже настроены регулярные бэкапы через cron, логику удобно объединить — у нас есть отдельная статья про автоматические бэкапы на Ubuntu 24.04 с нуля, подход из неё применим и к каталогу /mnt/minio-data.

Для мониторинга состояния у MinIO есть встроенный health-эндпоинт, который можно опрашивать любой системой мониторинга:

curl -I http://127.0.0.1:9000/minio/health/live

Ответ 200 OK значит, что сервис жив и принимает запросы. Метрики в формате Prometheus отдаются по адресу /minio/v2/metrics/cluster — если в инфраструктуре уже крутится связка Prometheus и Grafana, добавить туда MinIO как ещё один таргет — вопрос одной строчки в конфиге скрейпера.

Обновление MinIO делается заменой бинарника — обратной совместимости данных при этом MinIO придерживается строго:

systemctl stop minio
wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
chmod +x /usr/local/bin/minio
systemctl start minio

Перед обновлением на проде стоит свериться с release notes на сайте проекта — редко, но случаются breaking changes в поведении API или флагов запуска.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Чем MinIO отличается от обычного файлового сервера на Nginx?

MinIO даёт S3-совместимый API поверх файлов — с бакетами, версионированием объектов, политиками доступа и presigned URL, а не просто раздачу статики по пути. Для приложений, которые уже умеют работать с S3 SDK, это готовая интеграция без переписывания кода.

Можно ли использовать MinIO вместо AWS S3 в проде?

Да, множество компаний так и делают — именно ради контроля над данными и стоимости. Ограничение в том, что при single-node конфигурации вы сами отвечаете за резервирование; для серьёзной отказоустойчивости изучайте multi-node развёртывание с erasure coding.

Нужен ли отдельный диск под данные MinIO?

Не обязательно для старта, но крайне желательно для продакшена — так проще следить за заполнением места и не зависеть от системного раздела, на котором живёт ОС и логи.

Как ограничить доступ к MinIO по IP?

Проще всего — правилами UFW/iptables для портов 9000 и 9001 (или единого входа через Nginx, если решите не закрывать порты полностью), либо через allow в конфиге Nginx перед проксированием на внутренние порты.

Работает ли с MinIO стандартный AWS CLI и SDK?

Да, достаточно указать --endpoint-url https://s3.example.com в AWS CLI или передать кастомный endpoint в SDK (boto3, aws-sdk-js и т.д.) — остальной код с S3 меняется минимально или не меняется вовсе.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →