S3 스토리지 활성화 시 아바타 업로드 실패 (파일 존재에도 계속 오류)

안녕하세요,

Discourse + S3 스토리지에서 이상한 문제를 겪고 있습니다.

아바타를 업로드하면 아래와 같은 오류가 발생합니다. S3 버킷에 해당 파일이 실제로 존재하며 유효한 s3_cdn_url을 통해 접근 가능한 상태인데도 말이죠.

게시물과 첨부 파일 업로드는 완벽하게 정상 작동합니다. 실패하는 것만은 사용자 아바타 업로드입니다.


:fire: gig.ovh/logs에서 확인된 오류 메시지


Message (2 copies reported)

Could not find file in the store located at url: //gig.s3.ru-1.storage.selcloud.ru/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

Backtrace

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\_support/broadcast\_logger.rb:134\:in `block in error'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\_support/broadcast\_logger.rb:231\:in `each'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/broadcast_logger.rb:231:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active\_support/broadcast\_logger.rb:134\:in `error'
/var/www/discourse/app/models/optimized_image.rb:91:in `block in create\_for'
/var/www/discourse/app/models/optimized\_image.rb:19\:in `block (2 levels) in lock'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed\_mutex.rb:49\:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed\_mutex.rb:34\:in `synchronize'
/var/www/discourse/app/models/optimized_image.rb:19:in `block in lock'
/var/www/discourse/lib/distributed\_mutex.rb:53\:in `block in synchronize'
/var/www/discourse/lib/distributed\_mutex.rb:49\:in `synchronize'
/var/www/discourse/lib/distributed\_mutex.rb:49\:in `synchronize'
/var/www/discourse/lib/distributed\_mutex.rb:34\:in `synchronize'
/var/www/discourse/app/models/optimized\_image.rb:18\:in `lock'
/var/www/discourse/app/models/optimized_image.rb:83:in `create\_for'
/var/www/discourse/app/models/upload.rb:151\:in `get_optimized_image'
/var/www/discourse/app/controllers/user_avatars_controller.rb:219:in `get\_optimized\_image'
/var/www/discourse/app/controllers/user\_avatars\_controller.rb:137\:in `show_in_site'
/var/www/discourse/app/controllers/user_avatars_controller.rb:90:in `block (2 levels) in show'
/var/www/discourse/lib/hijack.rb:68\:in `instance_eval'
/var/www/discourse/lib/hijack.rb:68:in `block (2 levels) in hijack'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/i18n-1.14.7/lib/i18n.rb:353\:in `with_locale'
/var/www/discourse/lib/hijack.rb:68:in `block in hijack'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:911\:in `callback_on_resolution'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:797:in `call\_callback'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:803\:in `call_callbacks'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:692:in `resolve\_with'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb:1325\:in `resolve'
/var/www/discourse/lib/scheduler/defer.rb:125:in `block in do\_work'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails\_multisite-6.1.0/lib/rails\_multisite/connection\_management/null\_instance.rb:49\:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with\_connection'
/var/www/discourse/lib/scheduler/defer.rb:119\:in `do_work'
/var/www/discourse/lib/scheduler/defer.rb:105:in `block (2 levels) in start\_thread'

컨테이너의 S3 URL은 다음과 같습니다.

//gig.s3.ru-1.storage.selcloud.ru/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

이미지는 다음 URL에서 접근 가능합니다:

https://s3.gig.ovh/original/1X/fd42dfa3362b66090450f2ae40f0917193fcd355.jpeg

:white_check_mark: 추가 정보

  • Discourse 버전: (최신 안정판)
  • 외부 S3 호환 스토리지 사용 (enable_s3_uploads = true)
  • s3_cdn_url이 올바르게 설정되어 있으며 사용 중
  • CDN URL이 파일을 성공적으로 반환함
  • 파일이 예상된 S3 위치에 실제로 존재하는지 확인됨
  • 기타 업로드(이미지, 첨부 파일 등)는 정상 작동
  • 오류는 사용자 아바타에서만 발생

:red_question_mark: 질문

정확한 파일이 존재하고 올바른 CDN URL을 통해 접근 가능한데, 왜 Discourse가 아바타 처리를 위해 파일을 가져오지 못하는 것일까요?

아바타 처리(get_optimized_image 등)에 특정한 설정 오류나 캐시 오류가 있을 수 있나요?

제안이나 통찰이 있다면 감사하겠습니다!

감사합니다 :folded_hands:

안녕하세요 — 이 문제를 해결하셨나요?

저도 Discourse + S3 환경에서(아바타 파일만 해당) 정확히 같은 증상을 겪고 있습니다:
Could not find file in the store located at url: //<bucket>.s3.dualstack.<region>.amazonaws.com/original/1X/<hash>.jpeg

혹시 저와 환경이 일치하는지 확인해 보실 수 있도록 제 설정에 대한 몇 가지 세부 사항을 공유합니다:

  • enable_s3_uploads = true, 객체는 original/*optimized/* 경로에 위치해 있습니다 (uploads/default 접두어 없음)

  • CloudFront(OAC)를 통해 접근하며, 버킷 자체는 비공개로 설정되어 있습니다

  • 해당 키에 객체는 실제로 존재하며, CDN URL은 정상 작동합니다

  • 오류는 아바타 처리 시에만 발생합니다

  • (가능한 문제점) 업로드 파일이 SSE-KMS로 암호화되어 있습니다

혹시 근본 원인을 찾거나 해결 방법(정책 변경, KMS 권한, 버킷 경로 정렬 등)을 찾으셨다면 어떤 방식으로 해결하셨는지 공유해 주실 수 있을까요? 감사합니다!