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

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

Однако, прежде чем я добавлю общее замечание вне раздела MinIO, можем ли мы подтвердить, что Discourse в целом больше не поддерживает пути, не основанные на доменах, как в этом посте, который стал отправной точкой для моего поиска?

Если мы знаем, что Discourse в целом не поддерживает режим путей (то есть пути вида minio.server.com/BUCKET/foo/bar/...), а поддерживает только доменные пути (то есть BUCKET.minio.server.com/foo/bar/...), то мы можем добавить это как глобальное уведомление в вики, и я с радостью это сделаю. Однако мне нужно услышать это от кого-то гораздо выше по иерархии, чем я (простой участник сообщества), что это действительно является требованием для Discourse. Если это так, я внесу соответствующие правки, в противном случае… ну, тогда я просто оставлю это как замечание в разделе требований к MinIO.

2 лайка

MinIO — это единственный популярный клон S3, который ранее использовал устаревший теперь путь S3, поэтому я не считаю, что требуется глобальное предупреждение; достаточно указать это только в разделе MinIO.

4 лайка

Спасибо, Фалько. Я оставил это в разделе требований к MinIO, но также сделал особый акцент на разделе с оговорками, так как в связанной выше теме объясняется, почему я снова поднимаю этот вопрос.

2 лайка

Похоже, возникла проблема:

Введено

  after_assets_precompile:
    - exec:
        cd: $home
        cmd:
          - sudo -E -u discourse bundle exec rake s3:upload_assets

Пересобрано:

FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && sudo -E -u discourse bundle exec rake s3:upload_assets завершилось с ошибкой, код возврата: #<Process::Status: pid 2064 exit 1>
Место ошибки: /usr/local/lib/ruby/gems/2.7.0/gems/pups-1.1.1/lib/pups/exec_command.rb:117:in `spawn'
Выполнение команды не удалось с параметрами {"cd"=>"$home", "cmd"=>["sudo -E -u discourse bundle exec rake s3:upload_assets"]}
Загрузка не удалась с кодом выхода 1
** ЗАГРУЗКА НЕ УДАЛАСЬ ** прокрутите вверх и поищите сообщения об ошибках, которые появились ранее; их может быть несколько.
./discourse-doctor может помочь в диагностике проблемы.
1 лайк

Можете ли вы следовать рекомендациям и

3 лайка

Добавлен шаг по очистке старых ресурсов на S3 в OP. Должно работать везде, кроме GCP.

3 лайка

Большинство из 170 000 файлов были загружены с помощью rake s3:migrate_to_s3, но, кажется, 12 из них вызвали следующую ошибку:

: Unsupported value for canned acl 'private' (Aws::S3::Errors::InvalidArgument)

Возможно, они были в личных сообщениях? Есть ли что-то, что я могу сделать, чтобы исправить это?

2 лайка

Привет @Falco. Это имеет смысл? Я просматриваю ответы, чтобы убедиться, что они обработаны, чтобы мы могли включить функцию удаления через 30 дней для этой темы.

Я проверил несколько загрузок, помеченных как приватные, и они находились в обычных темах, поэтому я не мог понять, почему они были помечены как безопасные. (Настройки безопасных загрузок не были включены?)

См. выше

2 лайка

Безопасные загрузки поддерживаются только в AWS S3, поэтому они действительно не будут работать ни с одним из их клонов.

2 лайка

Всё логично. Я добавил эту информацию в начало первого поста. Есть какие-то идеи, почему локальные загрузки могли быть помечены как защищённые на сайте, где не были включены S3 или защищённые загрузки?

1 лайк

Кто-то включил это на какое-то время, а затем откатил изменения, когда увидел, что это не работает?

2 лайка

Думаю, что эту проблему с загрузкой в Cloudflare R2 можно решить с помощью Upload.where(secure: true).update_all(secure: false). Постараюсь сделать это до удаления этого сообщения (но я добавил примечание к исходному посту).

2 лайка

Хм, у нас нет безопасных загрузок. Думаю, я попробую Cloudflare R2, так как у них довольно щедрые бесплатные лимиты, и у них есть (бета) мигратор S3. Я, наверное, сам узнаю, но вы видели, что R2 в итоге оказался приемлемым, @pfaffman?

1 лайк

Я больше не помню, возникала ли проблема при попытке загрузить изображения или когда я просто загрузил новое. Подумав еще раз, я склонен полагать, что я тестировал это на совершенно новом сайте.

Миграция на другую платформу S3 довольно сложна. Есть несколько тем на эту тему, но если вы хотите использовать Cloudflare R2, сначала попробуйте это на тестовом сайте; есть очень большая вероятность, что это не сработает.

1 лайк

Это вроде работает, но пока не готово к использованию в продакшене.

У меня была старая локальная установка Discourse 2.7 для разработки, которая работала нормально: загрузка изображений, использование CDN и резервное копирование в приватный бакет при настройке Cloudflare R2. Я обновился до последней версии 2.9 (как на нашем форуме), и теперь процесс догоняющих задач Jobs::UpdateGravatar завершается ошибкой. Проблема в том, что для Cloudflare используется неверная нотация бакета при попытке закэшировать удалённое изображение Gravatar в R2. Пример (мое имя бакета в R2 — ‘uploads’):

Upload Update (0.3ms) UPDATE "uploads" SET "url" = '//uploads.123123redact.r2.cloudflarestorage.com/original/1X/123123example.jpeg', "updated_at" = '2022-12-12 20:44:02.929494', "etag" = '9c02b086b2aa5e2088ed44e1017fa63e' WHERE "uploads"."id" = 3

При запуске UI аватары в моей локальной тестовой/разработной среде указывают на:

//uploads.123123redact.r2.cloudflarestorage.com/original/1X/123123example.jpeg

Мое предположение: для S3 нотация с точкой в имени бакета работает нормально, а для Cloudflare R2 — нет. Возможно, кэш Gravatar должен использовать значение CDN для S3? Жаль, что всё так близко к решению…

2 лайка

Я получил ответ от Cloudflare: для R2, пока они не реализуют ACL объектов корректно, они изменили поведение так, чтобы возвращать код 200, если в этом свойстве, которое они пока не поддерживают, передаются какие-либо значения. Это изменение поведения в R2 произошло, по-видимому, в конце ноября. Очевидно, это не идеальный вариант (ведь это публичный бакет, а API запрашивает его как приватный), но для данной проблемы это теперь «работает».

3 лайка

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

Я постараюсь посмотреть на это в самое ближайшее время.

2 лайка

Я использую отдельные бакеты для загрузки и резервного копирования, и всё работало нормально: бакет для резервных копий R2 не установлен как публичный, и Discourse через административный интерфейс успешно записал туда сжатую резервную копию. Я скачал её, просмотрел, и она выглядела корректно (не то же самое, что реальное восстановление, но достаточно хорошо для понедельника). Бакет для загрузок я протестировал с настройкой пользовательского домена для S3_CDN, и это тоже работает отлично.

Честно говоря, я не могу точно понять, что происходит с версией 2.9, которая не отображает интерфейс в ember-cli (экран пустеет после создания административного пользователя), но, скорее всего, вы быстро заметите проблему.

РЕДАКТИРОВАНИЕ: О, похоже, приложение пытается загрузить JavaScript-активы плагинов из Pseudo-S3/R2, например, много ошибок 404 на такие файлы, как assets/locales/en.br.js.

Команда bundle exec rake s3:upload_assets тоже не помогает, так что это пока лучшая подсказка.

РЕДАКТИРОВАНИЕ 2: Да, проблема связана с активами: если я очищаю переменную DISCOURSE_S3_CDN_URL, то интерфейс загружается. Пока попробую вручную загрузить активы в нужное место.

РЕДАКТИРОВАНИЕ 3: Похоже, проблема в том, что приложению требуются предварительно скомпилированные активы, и то, куда указывает DISCOURSE_S3_CDN_URL, не является обычным для локальной среды разработки. Буду с интересом ждать результатов @pfaffman, так как думаю, что это будет работать в правильно развёрнутом самодостаточном экземпляре Docker с использованием хука after_assets_precompile для R2.

2 лайка

Да. CDN для локальной среды разработки? Я не могу представить, чтобы это работало. Это звучит так, будто это должно работать для продакшн-развертывания.

1 лайк

Да, при размышлении назад это не удивительно в среде разработки. Я думаю, что я не ожидал, что при установке DISCOURSE_S3_CDN_URL в Cloudflare CDN для R2, а затем DISCOURSE_CDN_URL в пустое значение (или локальное, или ngrok), система всё равно захочет использовать Cloudflare pull URL для предварительно скомпилированных ассетов и т.д., а не только для загрузок и изображений. Я думаю, что в продакшене в правильном контейнере это будет работать нормально, так что, возможно, я попробую быстро. Мой план будет примерно таким: временно сделать загрузку медиафайлов через TL4, переключить ID и т.д. на Cloudflare в app.yaml, протестировать это и, если всё хорошо, оставить R2, а затем через rclone перенести все существующие объекты S3. После этого я пересоберу посты и, надеюсь, всё будет в порядке :crossed_fingers:.

2 лайка