Хранение и отдача файлов через MinIO
↑ 5.6 Генерация документов и отчётов · ← Предыдущая · → Следующая
Зачем это на собесе
Объектные хранилища — стандарт для файлов. Ждут понимания pre-signed URL и почему не хранить файлы в БД.
Объяснение
MinIO — S3-совместимое объектное хранилище (self-hosted). API совпадает с AWS S3, поэтому код переносится в облако.
| Понятие | Смысл |
|---|---|
| Bucket | контейнер объектов |
| Object | файл + метаданные, ключ (reports/2025/06/a1.pdf) |
| Pre-signed URL | временная подписанная ссылка на загрузку/скачивание |
| Lifecycle | правила удаления/перемещения по сроку |
| Versioning, Object Lock | версии и защита от удаления |
| Policies | права доступа на bucket/префикс |
var client = new MinioClient().WithEndpoint("minio:9000").WithCredentials(key, secret).Build();
await client.PutObjectAsync(new PutObjectArgs().WithBucket("docs").WithObject(objectKey)
.WithStreamData(stream).WithObjectSize(stream.Length).WithContentType("application/pdf"), ct);
// ссылка на скачивание на 10 минут
var url = await client.PresignedGetObjectAsync(new PresignedGetObjectArgs().WithBucket("docs").WithObject(objectKey).WithExpiry(600));Схема:
- В БД хранится только метаданные (id, ключ, размер, тип, владелец), файл — в MinIO.
- Загрузка большими файлами — pre-signed PUT прямо из браузера (multipart для больших), минуя ваш сервис.
- Ключ объекта генерируйте сами (GUID), оригинальное имя храните в метаданных.
- Виртуальная папка = префикс ключа.
Нюансы и подводные камни
- Публичный bucket по умолчанию не создавайте: доступ через pre-signed URL или прокси с проверкой прав.
- Pre-signed URL передаёт доступ любому, у кого ссылка: делайте срок коротким.
- Внутренний адрес MinIO ≠ публичный: ссылки для клиента должны использовать внешний хост.
- Файлы удаляйте вместе с записью (или lifecycle); осиротевшие объекты копят стоимость.
- Проверка типа и размера, антивирус для пользовательских загрузок.
Практика
- Поднимите MinIO в Docker и загрузите файл через SDK.
- Реализуйте загрузку из браузера по pre-signed PUT.
- Настройте lifecycle на удаление временных файлов через 7 дней.
Вопросы с ответами
Почему не хранить файлы в БД?
Раздувается БД и бэкапы, нагрузка на соединения; объектное хранилище дешевле и масштабируется.
Что такое pre-signed URL?
Временная подписанная ссылка, дающая доступ к объекту без учётных данных.
Чем MinIO полезен?
S3-совместимый API: код одинаково работает с MinIO и AWS S3.