Настройка провайдера объектного хранилища, совместимого с S3, для загрузки файлов

Пришлось пока отложить это, так как сначала казалось, что всё будет работать, но затем возникла странная проблема с R2, связанная с кодированием контента для ассетов — либо при загрузке не устанавливается заголовок, либо что-то ещё. Всё завершается ошибкой «Invalid or unexpected token» для сжатого файла вроде browser-detect-7af298cd000a967d2bdc01b04807eda2924a388584ea38ad84919b726283c2ed.gz.js. Команда rake s3:upload_assets вроде бы работает, но браузер не может корректно прочитать файлы.

Не совсем понимаю, почему для AWS S3 всё работает при использовании локального URL сервера для ассетов (они отсутствуют в нашем текущем S3-бакете для загрузок), а для R2 требуется использовать DISCOURSE_S3_CDN_URL только для ассетов. Если бы я мог принудительно указывать URL сервера для ассетов, скорее всего, всё бы заработало.

РЕДАКТИРОВАНИЕ: Обсуждая это в чате Cloudflare, выяснилось, что это и есть причина, и именно поэтому на сегодняшний день R2 нельзя использовать с Discourse без некоторых изменений. Я мог бы написать скрипт на этапе post hook для удаления сжатых .gz-файлов, но чувствую, что уже достаточно ушёл от основной задачи на сегодня:

Файлы, сжатые с помощью gzip, в настоящее время R2 обрабатывается неправильно. Необходимо загружать несжатые файлы. Cloudflare обеспечивает прозрачное сжатие: он выбирает identity, gzip или Brotli в зависимости от возможностей клиента. Это отличается от S3.

2 лайка

Отличная работа! И это ясное сообщение от Cloudflare о том, почему это не сработает. Большое спасибо. Я скоро добавлю это в первое сообщение.

2 лайка

Спасибо ещё раз! Я обновил первый пост:

3 лайка

Спасибо за создание этого руководства! У меня уже есть некоторый успех с использованием Minio.

Для всех остальных, кто пытается настроить его локально с помощью Docker Compose, вы можете указать Docker добавить алиас хоста, чтобы он работал как поддомен, например так:

  minio:
    image: minio/minio
    command: server --console-address :9001 /data
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - ./data/minio:/data
    environment:
      MINIO_DOMAIN: minio.mydomain.com
    networks:
      default:
        aliases:
          - assets.minio.mydomain.com

В этом случае вы установите DISCOURSE_S3_ENDPOINT=http://minio.mydomain.com:9000, DISCOURSE_S3_CDN_URL=//assets.minio.mydomain.com:9000 и настроите локальный файл /etc/hosts/, чтобы он указывал поддомен на localhost.

Это работает в основном нормально, но я заметил, что Discourse не может загружать файлы с адреса, который не имеет порта 80 или 443, поэтому загрузка изображения сработает, но при попытке загрузить его для изменения размера произойдет сбой.

Я подумал, что было бы хорошо упомянуть это в разделе Minio или в резюме, что DISCOURSE_S3_CDN_URL должен быть на порту 80 или 443.

4 лайка

Привет, @Falco! Это о том, как работает заголовок Content-Encoding: gzip с их CDN Spaces? Это звучит похоже на Cloudflare R2: расположение ресурсов сделано таким же, как у CDN для загрузки, из-за чего gzip ломается? Вот что происходит с R2 сегодня.

Стоит рассмотреть возможность добавления переключателя для этого поведения, то есть отдавать ресурсы напрямую из источника, а не всегда через DISCOURSE_S3_CDN_URL? Я с радостью изучу, как это реализовать, если это будет рассматриваться как потенциальное изменение конфигурации.

3 лайка

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

3 лайка

Да, я понимаю. Добавление нового булевого параметра GlobalSetting S3_ORIGIN_ASSETS (или S3_BROKEN_PROXY_FUDGE :slight_smile:) примерно в этом месте, аналогично тому, как это сделано для тестовых скриптов, которые не сжимаются, позволило бы Digital Ocean Spaces и Cloudflare R2 работать с Discourse «из коробки». Это было бы отличным дополнением при минимальных усилиях. Возможно, стоит рассмотреть в будущем. :heart_eyes_cat:

4 лайка

О, я видел в примечаниях к релизу 3.0.beta, что что-то добавлено. Я попробую, если только я не неправильно понял, для чего это? Это может позволить использовать Cloudflare R2 и Digital Ocean Spaces с их CDN, которые делают странную вещь с gzip.

1 лайк

Нет, это не связано.

3 лайка

Эта настройка позволила мне указать локальный сайт в качестве источника, чтобы обойти необходимость размещения js-активов на сайте S3 (в данном случае Cloudflare или Digital Ocean Spaces с включенным CDN). Спасибо @david за это изменение, даже если это не было изначальной целью.

4 лайка

Вы вводите URL сайта для CDN активов? Умно!

1 лайк

Всем привет, знает ли кто-нибудь, может ли это быть связано с Discourse?

Вот XML-файлы, которые мы пытались загрузить в наше ранее «работающее с Discourse» хранилище S3:

<Error>
<Code>InvalidArgument</Code>
<Message>
Запросы, указывающие шифрование на стороне сервера с использованием ключей, управляемых AWS KMS, требуют AWS Signature Version 4.
</Message>
<ArgumentName>Authorization</ArgumentName>
<ArgumentValue>null</ArgumentValue>
<RequestId>ID</RequestId>
<HostId>
ID
</HostId>
</Error>
1 лайк

Вы используете AWS или что-то другое?

Настроен ли этот бакет с серверным шифрованием?

Возможно, какая-то библиотека была обновлена и теперь работает иначе.

2 лайка

Спасибо, я перепроверил, и кажется, что это работает с автоматической конфигурацией, но не с управлением собственными ключами через S3 Management.

Подскажите, возможно ли это в Discourse?

1 лайк

3 сообщения были перенесены в новую тему: Зачем запускать UpdatePostUploadsSecureStatus, даже если безопасные загрузки отключены?

Похоже, эта проблема была недавно исправлена.
В списке изменений от 2023-03-16 указано исправление ошибки обработки файлов gzip.

В настоящее время мы запускаем наш форум Discourse на discourse.aosus.org с использованием R2 (еще не выполняли миграцию на S3), и всё работает нормально! На данный момент никаких заметных проблем не обнаружено.

  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: "us-east-1" #алиас для auto
  #DISCOURSE_S3_INSTALL_CORS_RULE: true #должно поддерживаться
  DISCOURSE_S3_ENDPOINT: S3_API_URL
  DISCOURSE_S3_ACCESS_KEY_ID: xxx
  DISCOURSE_S3_SECRET_ACCESS_KEY: xxxx
  DISCOURSE_S3_CDN_URL: ваш_адрес_cdn
  DISCOURSE_S3_BUCKET: ИМЯ_КОРЗИНЫ

Существует ли способ указать отдельные хосты для резервных копий? Было бы здорово, если бы можно было оставить R2 только для задач CDN.

2 лайка

Нет. Мне кажется маловероятным, что это изменится.

1 лайк

23 сообщения были перенесены в новую тему: Проблемы с настройкой объектного хранилища

Странно, что настройки в переменных окружения не отображаются в административном интерфейсе. Происходит ли переопределение? Будут ли новые настройки S3 в административном интерфейсе переопределять те, что заданы в окружении?

1 лайк

Да. Переменные окружения переопределяют значения в базе данных и скрыты от интерфейса пользователя.

4 лайка