업로드를 위해 S3 호환 객체 저장소 제공자 구성하기

@Falco - Scaleway에 대한 경고를 추가하는 것이 좋을 수 있습니다. Scaleway는 멀티파트 업로드에 1,000개 부분만 지원하지만, AWS는 10,000개를 지원하기 때문입니다. 이는 일반 업로드에는 문제가 되지 않지만, 특정 크기를 초과하는 백업 업로드에서는 문제가 됩니다. S3 SDK는 수동으로 수정하지 않는 한 10,000개 부분을 사용하므로 실패하게 됩니다.

4개의 좋아요

훌륭한 발견입니다! 가능하시면 OP 위키에 추가해 주세요.

4개의 좋아요

감사합니다. 또한, Rclone, Shargate, Gs Richcopy360, GoodSync와 같은 도구를 사용하여 클라우드 간 데이터를 복사할 수 있으며, 특히 S3 호환 오브젝트 스토리지와의 복사(상/하향)에 유용합니다. 이 도구들은 모두 유사한 클라우드 환경과 호환됩니다.

1개의 좋아요

방금 문제를 발견했습니다. Cloudflare R2는 S3 엔드포인트 URL에서 public-read를 허용하지 않으며, 커스텀 도메인 또는 랜덤 r2.dev 도메인에서만 허용합니다.
(프리사인 다운로드(Presigned downloads)는 작동하지만, 직접적인 공개 액세스는 지원되지 않습니다.)
하지만 Discourse는 임베드된 이미지에만 CDN URL을 사용하고, S3 엔드포인트 URL을 사용하는 직접 다운로드에는 사용하지 않습니다.
모든 파일에 대해 CDN URL을 사용하게 하거나, presigned URL 사용을 강제하는 방법이 있을까요?

관련 링크:

해당 게시물에서 언급된 우회 방법이 작동합니다. ?dl=1을 추가하면 Discourse가 presigned S3 URL을 사용하도록 강제되어 문제가 해결됩니다.

1개의 좋아요

2023-03-16에 수정되어, 이제 R2가 무료 플랜으로 Discourse와 완벽하게 작동합니다.

3개의 좋아요

저도 AWS Lightsail에서 Discourse를 실행하고 AWS S3로 업로드하고 있음에도 불구하고 가끔(몇 달에 한 번씩) 이런 문제를 겪고 있습니다. 따라서 이것이 Wasabi의せい 때문이라고 단정할 수 없습니다.

이 오류를 감지하여 관리자에게 알림을 보내는 것이 가능할까요? 업그레이드할 때 디스크 공간을 확인하고 오래된 백업을 삭제하긴 하지만, 때로는 그 때가 너무 늦어 디스크 공간 부족으로 포럼이 다운되는 경우가 있습니다.

1개의 좋아요

백업이 실행되는 동안 보안 업데이트를 위해 운영체제가 자동으로 재부팅되었기 때문이라고 거의 확신합니다. 운영체제 재부팅과 백업 시간을 서로 다른 시간으로 예약하는 것이 좋습니다. 이 설명을 생각해 낸 것은 해당 사이트를 wasabi에서 다른 곳으로 옮긴 후였지만, 그것이 원인이라고 꽤 확신합니다.

2개의 좋아요

uptime 명령을 실행해 보니 300일째 가동 중이므로, 이것이 문제라고 생각하지는 않습니다. 하지만 비슷한 맥락에서, Discourse 백업은 오전 2:00에, Lightsail 스냅샷은 오전 2:30에 예약되어 있었습니다. 그래서 업로드가 완료되지 않은 상태에서 스냅샷이 생성되어 문제를 일으키는 것일 수도 있겠더군요. 두 작업을 1시간 간격으로 분리해 보았으니, 차이가 있을지 지켜보겠습니다.

어쨌든, 업로드가 실패하는 이유를 불문하고 관리자에게 이를 경고하는 것이 합리적이라고 생각합니다.

2개의 좋아요

커널 업그레이드 후 재부팅을 할 때가 된 것 같네요. :slight_smile:

RAM이 부족해서 그런 건가요?

원격 Backblaze 백업을 설정한 후 대시보드에서 다음 오류가 표시됩니다:

서버가 파일을 S3로 업로드하도록 설정되어 있지만, S3 CDN이 설정되어 있지 않습니다. 이로 인해 S3 비용이 증가하고 사이트 성능이 저하될 수 있습니다. 자세한 내용은 "업로드를 위한 객체 저장소 사용"을 참고하세요.

저는 파일 업로드를 설정한 적이 없고, 다음 설정을 통해 백업만 구성했습니다:

DISCOURSE_S3_REGION: "s3.us-west-00X"
DISCOURSE_S3_INSTALL_CORS_RULE: false
DISCOURSE_S3_ENDPOINT: https://s3.us-west-00X.backblazeb2.com
DISCOURSE_S3_ACCESS_KEY_ID: mykeyid
DISCOURSE_S3_SECRET_ACCESS_KEY: myaccesskey
DISCOURSE_S3_BUCKET: community-forum
DISCOURSE_S3_BACKUP_BUCKET: community-forum/backups
DISCOURSE_BACKUP_LOCATION: s3

무엇을 잘못 설정한 것일까요?

무언가 잘못 설정된 것 같습니다. 게시글에 파일을 업로드하려고 하면 다음과 같은 오류가 발생합니다:

Unsupported value for canned acl ‘public-read’

도움을 주시면 감사하겠습니다.

2개의 좋아요

업로드가 s3로 전송되지 않도록 하려면 이 항목을 삭제하세요.

4개의 좋아요

형, 정말 큰 도움 됐어. :+1:t3: 정말 고마워!

2개의 좋아요

그렇게 했더니 효과가 있었나요?

1개의 좋아요

두 프로세스를 1시간 간격으로 분리한 이후 지난 한 달 동안 한 번만 발생했기 때문에 문제가 "해결"된 것은 아니며, 발생 빈도가 낮아 도움이 되었는지 판단하기 어렵습니다.

다행히도 관리자 페이지에 백업 상태 섹션이 있다는 것을 알게 되었는데, 여기에는 사용 가능한 디스크 공간이 표시되어 있습니다. 덕분에 막혀 있는 백업을 확인하기 위해 터미널을 계속 열고 df 명령을 실행할 필요가 없어졌습니다. 약 80GB의 여유 공간이 있어야 한다는 점을 상기시키기 위해 텍스트를 직접 수정해 두었습니다.

1개의 좋아요

좋은 아이디어네요.

텍스트를 커스터마이징했다는 내용을 읽기 전에 이미 그 이미지를 봤었는데, 무엇이 "좋다"고 판단했는지 그 기준이 궁금했습니다!

1개의 좋아요

Scaleway를 Bitnami Discourse 이미지와 함께 사용하려고 했지만 어떻게 해도 작동하지 않았습니다.
환경 변수는 설정되어 있었지만, 명확히 올바르게 읽히거나 적용되지 않고 있었습니다(아니면 아예 적용되지 않는 건지).

그래서 관리자 패널에서 S3 변수를 설정하고, rails 콘솔에서 리전을 직접 설정했습니다(이것이 그냥 텍스트 필드로 바뀌길 여전히 희망하면서):
SiteSetting.s3_region="fr-par"

검증 오류가 발생했지만, 설정을 업데이트하기 전에 검증 체크를 주석 처리했고, 나중에 다시 원래대로 되돌렸습니다.

1개의 좋아요

Bitnami 이미지는 우리가 패키징한 것이 아니며, 우리의 권장 사항을 따르지 않습니다. 여기에 문서화된 모든 내용은 공식 설치 환경에서만 테스트되었습니다.

4개의 좋아요

이 문제는 discourse에서 최근 추가된 “s3 use cdn url for all uploads” 옵션을 활성화함으로써 해결되었습니다.
이전에 R2를 사용했기 때문에, 깨진 링크를 수동으로 교체하기 위해 discourse remap을 사용해야 했으며, 보험 차원에서 s3 파일도 동기화한 후 모든 게시물을 다시 재처리(rebake)했습니다.

1개의 좋아요

idrive e2(와 S3 호환)로 이 설정을 시도하고 있습니다. 하지만 ./launcher rebuild app 실행 시 끝에 도움이 되지 않는 오류/스택 트레이스가 표시됩니다:

I, [2023-10-14T15:08:08.026184 #1]  INFO -- : > cd /var/www/discourse && sudo -E -u discourse bundle exec rake s3:upload_assets
rake aborted!
Aws::S3::Errors::InternalError: We encountered an internal error, please try again.
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/raise_response_errors.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/dualstack.rb:27:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/plugins/accelerate.rb:56:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/checksum_algorithm.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/idempotency_token.rb:19:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/param_converter.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/request_callback.rb:71:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/aws-sdk-core/plugins/response_paging.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/plugins/response_target.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-core-3.130.2/lib/seahorse/client/request.rb:72:in `send_request'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/client.rb:12369:in `put_object'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/aws-sdk-s3-1.114.0/lib/aws-sdk-s3/object.rb:1472:in `put'
/var/www/discourse/lib/s3_helper.rb:78:in `upload'
/var/www/discourse/lib/tasks/s3.rake:41:in `block in upload'
/var/www/discourse/lib/tasks/s3.rake:41:in `open'
/var/www/discourse/lib/tasks/s3.rake:41:in `upload'
/var/www/discourse/lib/tasks/s3.rake:197:in `block (2 levels) in <main>'
/var/www/discourse/lib/tasks/s3.rake:197:in `each'
/var/www/discourse/lib/tasks/s3.rake:197:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rake-13.0.6/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
Tasks: TOP => s3:upload_assets
(See full trace by running task with --trace)
I, [2023-10-14T15:08:16.413098 #1]  INFO -- : Installing CORS rules...
skipping
Uploading: assets/admin-2ebebf57104b0beb47a1c82fe5a8c6decd07f60a706640345fed296a094d1536.js

아래 설정을 사용하고 있으며, DISCOURSE_S3_CONFIGURE_TOMBSTONE_POLICY와 DISCOURSE_S3_HTTP_CONTINUE_TIMEOUT을 추가하여도 시도해 보았습니다.

  DISCOURSE_USE_S3: true
  DISCOURSE_S3_REGION: Dallas
  DISCOURSE_S3_ENDPOINT: https://y0o9.tx21.idrivee2-4.com
  DISCOURSE_S3_ACCESS_KEY_ID: <snip>
  DISCOURSE_S3_SECRET_ACCESS_KEY: <snip>
  DISCOURSE_S3_BUCKET: discourse
  DISCOURSE_S3_INSTALL_CORS_RULE: false

참고로 백업에는 이 설정을 사용하지 않고 있습니다(백업은 이미 UI에서 backblaze로 설정되어 있음). 또한 idrive가 이를 지원하는지 확신이 서지 않아 DISCOURSE_CDN_URL도 사용하지 않았습니다. 버킷에 실제 파일이 몇 개 들어간 후 CDN 설정 실험을 계획하고 있습니다.

1개의 좋아요

S3와 Discourse의 요구사항에 충분히 호환되지 않는 것 같습니다.

더 자세히 조사하려면 다음 단계는 개발 환경에서 이를 재현하고 실패하는 정확한 API 호출을 확인하는 것입니다.

2개의 좋아요