Храним файлы Strapi в облаке Selectel
- суббота, 17 февраля 2024 г. в 00:00:15
Привет, я некоторое время работаю над своим пет проектом, где в основном занимаюсь фронтом, а для данных использую headless CMS под названием strapi.io. В какой-то момент у меня появилась потребность вынести медиа хранилище из локальной папки в облако. А так-как основной проект уже находился долгое время на серверах Selectel, я решил воспользоваться их объектным хранилищем и подключится к нему с помощью плагина “@strapi/provider-upload-aws-s3“. И в этой статье я вам опишу краткий гайд как это сделать.
Для начала у вас уже должно быть strapi приложение, версии приближенной к 4.20.0, и аккаунт в Selectel. Открываем личный кабинет, ищем в сайдбаре раздел “Облачные услуги” и открываем вкладку “Объектное хранилище”. Кликаем кнопку “Создать контейнер” и видим следующий интерфейс.
Напишите имя, оно станет названием контейнера для s3, так что рекомендую использоваться только английские буквы и тире. Тип - публичный, ибо изображения будут доступны на сайте. И адресация - галочка на Virtual-Hosted, ниже пояснение из доки плагина.
AWS SDK V3 adopts the virtual-hosted–style URI format for S3 URLs. This format is recommended by AWS and is likely to become required in the near future, as the path-style URI is being deprecated. More details on this format can be found in the AWS User Guide.
Далее отправляемся в “Профиль и настройки”, там ищем вкладку "Управление пользователями” и нажимаем кнопку “Добавить пользователя”.
Переключаем тип на “Сервисный пользователь”, выбираем роль “Пользователь объектного хранилища” и указываем проект в котором мы создали контейнер. Добавляем пользователя и заходим в него, листаем до заголовка “S3 ключи”, нажимаем “Добавить ключ”, снова выбираем проект и генерируем Access key и Secret key.
Чтобы не потерять ключи, предлагаю сразу их добавить в переменную окружения.
# .env
AWS_ENDPOINT=https://s3.storage.selcloud.ru
AWS_REGION=ru-1
AWS_ACCESS_KEY_ID=<Access key>
AWS_ACCESS_SECRET=<Secret key>
AWS_BUCKET=<Название контейнера>
В проект strapi устанавливаем “@strapi/provider-upload-aws-s3“, добавляем конфигурацию провайдера.
// path: ./config/plugins.ts
export default ({ env }) => ({
upload: {
config: {
provider: "aws-s3",
providerOptions: {
s3Options: {
endpoint: env("AWS_ENDPOINT"),
credentials: {
accessKeyId: env("AWS_ACCESS_KEY_ID"),
secretAccessKey: env("AWS_ACCESS_SECRET"),
},
params: {
Bucket: env("AWS_BUCKET"),
},
},
},
},
},
})
Возвращаемся в Selectel, нам осталось выдать новому пользователю права на доступ к конкретному контейнеру. Переходим в нашем контейнере, во вкладку “Политика доступа” и нажимаем “Создать политику доступа”.
Пользователи - выбираем авторизованные и находим нового сервисного пользователя, набор действий - редактор. И добавим еще одно правило, для авторизованного пользователя панели со всеми доступными действиями, чтобы мы могли управлять контейнером из личного кабинета Selectel.
Нажимаем “Сохранить” и возвращаемся в интерфейс Strapi, чтобы протестировать загрузку.
Загрузка работает, но изображение не отображается, и над этим вопросом я долго ломал голову, но после крупного обновления личного кабинета Selectel решение нашлось очень быстро. В самом начале мы указали тип контейнера - публичный, и соответственно во вкладке “Домены” мы находим публичный домен для доступа к загруженным файлам. Добавляем его в файл окружения и прописываем в конфиге провайдера.
# .env
CDN_URL=<Публичный домен контейнера>
// path: ./config/plugins.ts
provider: "aws-s3",
providerOptions: {
baseUrl: env("CDN_URL"),
s3Options: {
...
А так же нам нужно подправить конфигурацию Content Security Policy (CSP), пример взят из доки провайдера.
// path: ./config/middlewares.ts
export default ({ env }) => [
...
{
name: "strapi::security",
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
"connect-src": ["'self'", "https:"],
"img-src": [
"'self'",
"data:",
"blob:",
"https://strapi.io",
"https://market-assets.strapi.io",
env("CDN_URL"),
],
"media-src": [
"'self'",
"data:",
"blob:",
"https://strapi.io",
"https://market-assets.strapi.io",
env("CDN_URL"),
],
upgradeInsecureRequests: null,
},
},
},
},
...
Удаляем тестовое изображение и загружаем заново. Теперь все работает.
Вместо публичного домена Selectel так же предлагает подключить свой собственный или воспользоваться услугой CDN. Но в этой статье на этом все. До встречи!