Ви запустили Strapi на продакшені, а через місяць файли губляться при деплої? Або бекенд падає під навантаженням при віддачі статики? Знайома ситуація: стандартна медіа-бібліотека Strapi зберігає все в public/uploads — зручно для розробки, але для продакшену критично. У цій статті розберемо налаштування сховища Strapi для продакшену. За 10 років ми налаштували медіа-бібліотеки для 50+ проектів на Strapi і знаємо, як уникнути цих проблем. Налаштовуємо хмарне сховище на основі S3, Cloudinary або R2, додаємо автоматичну оптимізацію зображень і контроль типів файлів. Розберемо грамотну конфігурацію, яка позбавить головного болю.
Локальне зберігання не вирішує три ключові проблеми. По-перше, файли не реплікуються між інстансами: при горизонтальному масштабуванні кожен сервер бачить лише свої файли. По-друге, локальні файли губляться при перескладанні контейнера (Docker перестворює шар). І нарешті, продуктивність: віддача статики через Node.js повільніша, ніж через CDN хмарного провайдера. Правильна конфігурація медіа-бібліотеки скорочує час завантаження сторінок на 30–40% і позбавляє від бекапних ризиків. За місяць локальне сховище може призвести до значних втрат через простої, а оптимізація зображень у одного клієнта зекономила суттєву суму на трафіку.
Чому не варто використовувати локальне сховище в продакшені?
Локальне сховище в public/uploads підходить тільки для розробки. На продакшені воно створює вузькі місця: відмовостійкість відсутня, масштабування ускладнене, а при кожному деплої файли можуть бути втрачені. Хмарне сховище вирішує всі ці проблеми: файли зберігаються централізовано, доступні з будь-якої точки світу через CDN, і не губляться при перезапуску контейнерів.
Якого провайдера обрати для медіа-бібліотеки Strapi?
| Провайдер | Пакет | Особливості |
|---|---|---|
| AWS S3 | @strapi/provider-upload-aws-s3 |
Гнучкі налаштування, інтеграція з CloudFront, зрілий SDK |
| Cloudinary | @strapi/provider-upload-cloudinary |
Вбудована оптимізація зображень, автоматичні формати (WebP, AVIF) |
| DigitalOcean Spaces | через aws-s3 |
S3-сумісний, фіксована ціна за 250 ГБ |
| Cloudflare R2 | через aws-s3 |
Нульова плата за egress, глобальна мережа доставки |
Cloudinary обробляє зображення в 2–3 рази швидше, ніж S3 з лямбда-функціями. R2 виграє за вартістю при великому обсязі трафіку — немає плати за вихідний канал.
Налаштування AWS S3
Встановіть пакет: npm install @strapi/provider-upload-aws-s3. Конфігурація в config/plugins.js:
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
s3Options: {
credentials: {
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_ACCESS_KEY_SECRET'),
},
region: env('AWS_REGION', 'eu-central-1'),
endpoint: env('AWS_ENDPOINT', undefined), // для S3-сумісних
params: {
ACL: env('AWS_ACL', 'public-read'),
Bucket: env('AWS_BUCKET'),
},
},
},
actionOptions: {
upload: {},
uploadStream: {},
delete: {},
},
},
},
});
Amazon S3 — об'єктне сховище від AWS, широко використовуване для зберігання файлів.
Налаштування Cloudflare R2
R2 сумісний з S3 API, безкоштовна egress смуга:
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
s3Options: {
credentials: {
accessKeyId: env('R2_ACCESS_KEY_ID'),
secretAccessKey: env('R2_SECRET_ACCESS_KEY'),
},
region: 'auto',
endpoint: `https://${env('CF_ACCOUNT_ID')}.r2.cloudflarestorage.com`,
params: {
Bucket: env('R2_BUCKET'),
},
},
},
},
},
});
Для публічного доступу до файлів потрібен кастомний домен R2 або Cloudflare Worker.
Налаштування Cloudinary
Встановіть пакет: npm install @strapi/provider-upload-cloudinary. Конфігурація:
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'cloudinary',
providerOptions: {
cloud_name: env('CLOUDINARY_NAME'),
api_key: env('CLOUDINARY_KEY'),
api_secret: env('CLOUDINARY_SECRET'),
},
actionOptions: {
upload: {
folder: env('CLOUDINARY_FOLDER', 'strapi'),
transformation: [{ quality: 'auto', fetch_format: 'auto' }],
},
uploadStream: {},
delete: {},
},
},
},
});
В одному проекті з 500 000 зображень ми перенесли медіатеку на Cloudinary за 2 дні, скоротивши час завантаження сторінки з 4.2 с до 1.1 с. Це стало можливим завдяки автоматичній оптимізації та CDN.
Формати зображень та брейкпоїнти
Strapi автоматично створює кілька розмірів при завантаженні. Налаштування в config/plugins.js:
breakpoints: {
xlarge: 1920,
large: 1000,
medium: 750,
small: 500,
xsmall: 64,
},
У відповіді API поле formats містить URL кожного варіанту. Розміри та типове використання:
| Розмір | Ширина (px) | Типове використання |
|---|---|---|
| xlarge | 1920 | Десктопні банери |
| large | 1000 | Статті, контент на десктопі |
| medium | 750 | Зображення в картках |
| small | 500 | Мініатюри в списках |
| xsmall | 64 | Іконки, аватари |
Фільтрація типів і обмеження розміру
Обмеження розміру завантаження та MIME-типів:
// config/plugins.js
module.exports = {
upload: {
config: {
sizeLimit: 20 * 1024 * 1024, // 20 МБ
},
},
};
// src/extensions/upload/strapi-server.js
module.exports = (plugin) => {
const originalUpload = plugin.controllers.upload.upload;
plugin.controllers.upload.upload = async (ctx) => {
const { files } = ctx.request;
const allowed = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
const invalid = Object.values(files).flat()
.filter(f => !allowed.includes(f.type));
if (invalid.length) {
return ctx.badRequest('Непідтримуваний тип файлу');
}
return originalUpload(ctx);
};
return plugin;
};
Процес налаштування
- Аналіз вимог: визначаємо об'єм файлів, бюджет, вимоги до продуктивності.
- Вибір провайдера: на основі вартості, географії користувачів, необхідності трансформацій.
- Налаштування провайдера: встановлення пакету, конфігурація змінних середовища, тестове підключення.
- Конфігурація брейкпоїнтів: підгонка розмірів під дизайн сайту (зазвичай 640, 1024, 1920).
- Фільтрація та ліміти: налаштування допустимих MIME-типів та максимального розміру.
- Міграція даних: перенесення існуючих файлів з локального диска та оновлення посилань в БД.
- Тестування: перевірка завантаження, відображення, продуктивності.
- Документування та навчання: передача інструкцій команді клієнта.
Деталі міграції
Міграція виконується за допомогою скрипта, який копіює файли з `public/uploads` в S3-кошик та оновлює записи в базі даних Strapi. Для кількох гігабайт процес займає 1-2 дні. Перед міграцією обов'язково створюється бекап бази даних і файлів. Після перенесення всі посилання в медіа-об'єктах вказують на хмарне сховище.Терміни
- Налаштування S3/R2/Cloudinary провайдера — кілька годин.
- Перенесення існуючих файлів з локального сховища — 1 день (залежить від об'єму).
- Кастомна фільтрація типів + обмеження — кілька годин.
Що входить в роботу
- Налаштування провайдера сховища (S3, Cloudinary, R2).
- Конфігурація брейкпоїнтів та оптимізація зображень.
- Реалізація фільтрації типів та розміру файлів.
- Міграція існуючих файлів на хмарне сховище.
- Написання документації та інструкцій для команди.
- Гарантія коректної роботи та підтримка протягом місяця після налаштування.
Отримайте консультацію з налаштування медіа-бібліотеки Strapi — допоможемо обрати оптимальне рішення та впровадимо без простоїв. Зв'яжіться з нами для обговорення вашого проекту. Замовте аудит поточної конфігурації — ми перевіримо, чи є вузькі місця.







