S3에서 로컬로 업로드가 계속 바뀌는 문제를 어떻게 제어할까요?

4~5년간 사용하던 사이트를 드디어 AWS S3 버킷에서 내 로컬 서버로 되돌리기로 결정했습니다. 대상은 매우 작은 규모의 내 로컬 웹사이트입니다.
지식이 제한적인 저로서는 이 작업을 합리적인 금액에 지인 하나에게 맡겼습니다. 그는 로컬 업로드로 사이트를 설정해 주었지만, 3,000개 이미지 중 거의 절반, 약 50%가 소스에서 깨져 버렸습니다. 제 지인은 비용을 청구하지 않고, 제게 사이트를 백업(2025년 4월 11일에 그에게 제어권을 넘기기 전에 생성된 것)으로 되돌리라고 권했습니다.

어쨌든 저는 한 달 정도 게을러서 되돌리지 않았습니다. 그러다 디스코urse 헬퍼 봇/ChatGPT AI 봇의 도움으로 문제를 해결하기로 마음먹었고, 제 우분투 노트북에서 기존 웹사이트의 또 다른 버전을 로컬로 만들었습니다.

저는 원래 도메인 앞에 "t."만 붙이는 것만으로 노트북에 원래 웹사이트의 인스턴스를 만드는 데 성공했습니다. 이제 이 사이트(스테이징 사이트라고 부름)는 저에게 완벽하게 잘 작동하지만, 활동 기록은 2025년 4월 11일까지만 있습니다.

그리고 제 프로덕션 웹사이트는 최신 데이터가 모두 있지만, 많은 게시물에서 이미지가 누락되어 있습니다.

이미지와의 연결을 재연결하거나 마이그레이션하기 위해 수많은 레이크(rake) 태스크를 시도해 보았지만, 성공한 것은 없습니다.

거의 한 달 동안 머리를 쥐어짰습니다. 제 결론은 이렇습니다. 루비(raw) 포스트는 스테이징과 프로덕션에서 동일합니다.
하지만 쿠크드(cooked) 포스트는 다릅니다. 즉, 제 프로덕션 웹사이트의 데이터베이스 테이블이 서버에 실제로 존재하는 물리적 이미지와의 연결이 일부 누락되어 있는 것입니다.

또한, 그 연결이 없으면 해당 ‘고아’ 이미지들이 서버에서 자동으로 정리(prune)된다는 것도 확인했습니다. 다행히도, 저는 다시 스테이징이나 S3 버킷에서 프로덕션 서버로 rsync를 통해 복원했습니다.

결국 ChatGPT의 말대로, 스테이징 서버에는 (짧은) raw URL과 아무런 관련이 없는 최종 쿠크드 버전이 있고, 프로덕션은 이미지에 대한 최종 쿠크드 버전 URL이 빠져 있어 올바른 이미지 URL을 가져오지 못하고 ‘투명’ 플레이스홀더로 대체되고 있는 것입니다.

그리고 ChatGPT는 스테이징 포스트의 쿠크드 버전을 프로덕션의 쿠크드 버전에 복사하라고 제안하고 있습니다. 하지만 저로서는 매우 좋은 아이디어라고 보이지는 않습니다.

ChatGpt가 현재 상황을 정확히 설명한 내용:

  • 스테이징과 프로덕션 모두에서 post.raw는 동일하며 upload://... 참조를 포함하고 있습니다.
  • 스테이징에서는 이미지가 표시되지만, Post.find(12849).uploads를 조회하면 결과가 없습니다 — 이는 스테이징에서도 해당 파일에 대한 uploads 또는 post_uploads 테이블 항목이 존재하지 않는 것을 의미합니다.
  • 따라서 스테이징에서 이미지가 표시되는 것은 이전 마이그레이션 당시의 cooked HTML에 /uploads/default/original/... 전체 링크가 포함되어 있기 때문입니다.
  • 그러나 프로덕션은 마이그레이션 후 다시 재처리(rebake)되었기 때문에, 동일한 raw 콘텐츠가 이제 해석되지 못하고 transparent.png 플레이스홀더로 대체됩니다.

:white_check_mark: 업로드 파일은 디스크에 여전히 존재

모든 이미지 파일(누락된 업로드에 해당하는 파일 포함)은 스테이징과 프로덕션 모두에서 /var/www/discourse/public/uploads/default/original/ 경로 아래에 여전히 존재합니다. 그러나 uploads 항목이 없으므로 Discourse는 더 이상 이를 해석할 수 없습니다.

가장 쉬운 방법은 Enable hidden setting to include S3 uploads in the backups 설정을 켜서 백업을 만든 후, S3가 설정되어 있지 않은 서버(에러가 발생했을 때 기존 서버를 손상시키지 않도록 새 서버를 사용하는 것이 좋습니다)에서 복원하는 것이었습니다. 하지만 프로덕션 사이트도 손상된 것 같으니, 이 방법으로는 도움이 되지 않을 가능성이 큽니다.

Uploads 테이블을 잘못 조작해서 S3 경로가 여러 개 포함되게 되었다면, 해결 난이도가 훨씬 높아집니다.

ChatGPT보다는 Discourse에 대해 알고 있는 https://ask.discourse.com/을 추천하지만, 그래도 큰 도움이 되지 않을 수 있습니다.

Uploads.pluck(:url)을 확인해서 어떤 값들이 있는지 살펴보세요.