복원 후 아바타가 사라졌습니다. 어떻게 다시 가져올 수 있나요?

@ariznaf, 좋은 아침입니다.

그 결론에 도달하기 전에, 모든 설치 환경으로 이동하여 각 설치 환경의 공유 폴더로 들어가서, 각 설치 환경에 대해 다음 명령어를 실행한 후 결과를 여기에 올려 주시겠어요?

# du -sh uploads

예를 들어, 저희 설치 환경에서는 이렇게 실행했습니다:

원본 설치:

# du -sh uploads
2.5G uploads

소켓 전용 설치 (문제를 수정하기 전):

# du -sh uploads
444K uploads

이것은 제가 업로드 폴더를 수동으로 복사해야 한다는 것을 알아내는 데 필요한 단서를 제공해 주었고, 문제를 알게 되자 해결책은 간단해졌습니다.

모든 공유 디렉터리에서 다른 uploads 폴더들을 du -sh uploads 명령어로 확인하면, 현재 무슨 일이 일어나고 있는지 파악하는 데 귀중한 단서를 얻을 수 있습니다.

크기가 서로 다르다면, 일부 업로드 파일이 누락되었음을 알 수 있으며 이를 수동으로 수정할 수 있습니다.

모두 크기가 동일하다면 (가능성은 낮지만), 문제는 더 흥미로워집니다 :slight_smile:

문제를 찾았습니다 (해결책은 아직 아닙니다).
문제는 복원 자체의 문제가 아니라 서버 이름을 변경한 데 있습니다.

혹시 누락된 단계가 있는지 확인하기 위해 복원 과정을 설명드리겠습니다.

GitHub에서 discourse의 새 복사본을 다운로드했습니다.
docker-setup 프로세스를 실행했습니다.
앱을 실행하고 복원을 진행하기 전에 app.yml을 편집하여 소켓 접근을 구성했습니다.
그리고 호스트 이름을 b.domain.com으로 변경했습니다 (기존에는 a.domain.com이었음).

nginx 리버스 프록시를 SSL로 구성하여 443 HTTPS 트래픽을 discourse 소켓으로 전달하도록 설정했습니다.
그 후 재빌드(launcher rebuild app)하고 nginx를 재시작했습니다(service nginx restart).
https://b.domain.com에 접근하여 discourse의 초기 설정을 진행했습니다.
S3에서 복원하도록 설정하고 데이터베이스와 업로드(썸네일 제외)의 마지막 백업을 복원했습니다.
복원 후에는 로그아웃 상태가 됩니다.
기존 사이트의 app.yml을 복사하여 동일한 설정과 플러그인을 가져오기 위해 app.yml을 편집했습니다.
app.yml의 호스트 이름을 b.domian.com으로 변경했습니다.

다시 재빌드하고 nginx를 재시작했습니다.

문제는 여전히 지속됩니다: 프로필을 변경한 모든 사용자의 프로필 이미지(미니멀)가 그 흰색 기본 프로필 이미지로 대체되었습니다.
왼쪽 상단의 우리 로고도 사라졌습니다.

@Stephen force_https는 켜져 있었습니다(기존 서버와 동일하게, 문제 없이). 활성화와 비활성화를 시도했지만 효과가 없었습니다. 사이트가 https로 접근되기를 원하므로 켜둔 상태로 두었습니다(어쨌든 http:80 트래픽은 nginx 설정에서 https:443으로 영구 리다이렉트됩니다).

@riking sidekiq을 사용하여 avatarmissing 작업을 트리거했는데 몇 밀리초 만에 정상적으로 완료된 것으로 보였습니다. 긴 과정일 수 있으니 24시간 정도 기다려 프로필 이미지가 재구성되는지 확인했습니다.
하지만 오늘도 같은 문제가 발생합니다: 프로필 이미지를 업로드한 사용자의 아바타 이미지가 없고 로고 이미지도 없습니다.

그 후 @Stephen의 제안대로 문제가 이름 변경 때문인지 확인해 보기 위해 시도했습니다.

app.yml과 nginx의 호스트 이름을 원래 이름인 a.domain.com으로 되돌리고 재빌드 후 nginx를 재시작했습니다.
로컬 hosts 파일을 수정하여 a.domain.com이 새 서버의 IP를 가리키도록 하고, ping을 통해 새 IP에 접근하고 있는지 확인했습니다.

그리고 바로! 아바타와 프로필이 정상적으로 표시됩니다.

따라서 문제는 복원 자체의 문제가 아니라, 어딘가에 URL의 전체 경로가 저장되어 있고 잘못된 위치에서 접근을 시도하고 있기 때문입니다.
어쨌든 기묘한 점은, 기존 서버가 여전히 실행 중이라는 것입니다(새 서버가 아니라 기존 서버에서 이미지를 찾았어야 했으므로, 잘못된 위치에서도 이미지를 찾았어야 했습니다).

하지만 어쨌든 문제는 복원 과정이나某种 손상 때문에 이미지를 다시 업로드해야 하는 문제가 아닙니다.

문제는 서버 이름 변경입니다.

이제 질문은 discourse 포럼을 하나의 도메인/호스트명에서 다른 곳으로 이동하는 방법이 무엇인지입니다.

호스트 이름을 다시 b.domain.com으로 변경해 보았습니다.

하지만 여전히 문제가 해결되지 않습니다.

구 이름을 사용할 때는 정상적으로 동작하는 것 같습니다(하지만 이제 구 서버가 여전히 온라인 상태라서 이미지 등을 구 서버에서 가져오는 것 같다는 의심을 하고 있습니다. hosts 파일에서 a.domain.com의 IP를 변경했음에도 구 서버에서 새 게시물과 새 게시물에 대한 알림을 받고 있기 때문입니다).

호스트 이름을 변경하기 위해 이 게시물의 지침을 따랐습니다.

discourse에서 a.domain.com을 b.domain.com으로 다시 매핑하면 문제가 해결될 줄 알았습니다.
또한 rake postes:rebake를 실행해 보았지만 결과는 동일합니다.

아바타와 로고가 사라졌고, 게시물에 삽입된 이미지들도 모두 사라졌습니다.

마지막으로, @neounix님이 제안하신 대로 shared/standalone/uploads/의 목적지를 교체하기 위해 모든 업로드를 다시 untar했지만, 여전히 운이 없게도 결과는 동일합니다.

데이터베이스에 실제로 유용한 정보가 있는 건가요? 서버 이전을 신경 쓰지 않고 처음부터 새로 시작하는 편이 더 쉬울 수도 있습니다.

몇 달 전 포럼이 시작된 시점부터의 모든 데이터와 게시글은 어떻게 되나요?

이미 말씀드린 바와 같이, 서버를 중지한 뒤 모든 데이터를 새 서버로 복사하고 다시 시작하는 방식으로 서버를 이전하는 것 자체는 성공했습니다.

하지만 지원팀에서 올바른 방법은 표준 백업 기능을 사용해 데이터베이스를 복원하는 것이라고 알려주었습니다.

그렇게 하려 시도하고 있지만, 매번 어떤 형태로든 문제가 발생합니다.

실서버에서 적용하기 전에 플러그인, 변경 사항 또는 업그레이드의 영향을 테스트하기 위해 테스트용 서버도 필요합니다.

서버가 충돌할 때까지 기다렸다가 그때 복원이 가능한지 확인해 볼 수는 없습니다.

지금까지 진행한 복원 테스트는 모두 어떤 형태로든 문제가 발생했고, 이미지나 기타 항목이 손실된 비기능 상태의 시스템으로 끝났습니다.

이 사가(saga)를 따라가며:

https://meta.discourse.org/t/postgresql-12-update/151236/193

“다른 discourse 인스턴스에서 백업 및 복구” 방법을 시도해 보았고, 이제 이 문제에 직면해 있습니다. 책에 나와 있는 모든 트릭(Sidekiq Job, Rebake 등)을 시도해 보았지만… 이것이 발생할 수 있는 원인에 대한 '단서’라도 있을까요? 제가 뭔가 알아볼 수 있도록 말입니다.

(여러분께 한 가지는 인정해야 하는데, 이 모든 일로 인해 저는 “아, 이 정도는 이해하는구나” 수준에서 PostGreSQL 박사, Redis 박사 수준으로 올라가고 있습니다… :stuck_out_tongue: Ruby와 로컬 개발 환경만 익숙해지면 커뮤니티에 유용한 사람이 될 수 있을지도 모릅니다 :P)

모든 아바타가 사라졌나요, 아니면 일부만 사라졌나요? 커스텀 아바타는 기본적으로 Uploads입니다. 다른 업로드들은 정상적으로 작동하나요?

Rails 콘솔로 이동하여 데이터베이스에서 작동하지 않는 아바타의 레코드를 확인해 보세요. URL, filesize, width, height, extension 값이 올바르게 설정되어 있나요?

User.find_by_username('Overgrow').user_avatar
User.find_by_username('Overgrow').uploaded_avatar

최적화 버전도 존재해야 합니다. 아래 방법으로 확인할 수 있습니다:

OptimizedImage.where(upload_id: upload_id).where(version: 2)

우선 도움을 주셔서 정말 감사합니다 @Overgrow.

모든 아바타와 이모지(그리고 헤더 같은 사이트 이미지 등)는 “있긴 했지만” 보이지 않았습니다. 아바타가 아닌 것들은 깨진 이미지처럼 보이고, 아바타의 경우 회색 플레이스홀더가 표시됩니다. 일부 사용자는 새 이미지를 업로드하면 보이는 경우가 있었습니다.

받은 명령어를 실행해 본 결과:

FATAL:  the database system is in recovery mode

그러니까… 이게 문제입니다 :eyes: (저는 "접속 끊김"이 많이 발생하는데, 데이터베이스와 관련이 있을지도 모르겠습니다.)

하지만 결국 _persist_가 된 후:

User.find_by_username(‘Overgrow’).user_avatar

=> #<UserAvatar:0x000055702722d200
 id: 4,
 user_id: 3,
 custom_upload_id: 20504,
 gravatar_upload_id: 12240,
 last_gravatar_download_attempt: Thu, 21 May 2020 10:16:55 UTC +00:00,
 created_at: Sat, 30 May 2019 16:33:16 UTC +00:00,
 updated_at: Thu, 21 May 2020 10:16:55 UTC +00:00>

(오늘 새 이미지를 업로드해 봤지만 작동하지 않습니다).

User.find_by_username(‘Overgrow’).uploaded_avatar

=> #<Upload:0x00005555cd911b58
 id: 20504,
 user_id: 3,
 original_filename: "16_2.png.jpg",
 filesize: 56220,
 width: 360,
 height: 360,
 url: "/uploads/default/original/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8.jpeg",
 created_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 updated_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 sha1: "63347a46c0ca945f53613722a73c233484d642c8",
 origin: nil,
 retain_hours: nil,
 extension: "jpeg",
 thumbnail_width: 360,
 thumbnail_height: 360,
 etag: nil,
 secure: false,
 access_control_post_id: nil,
 original_sha1: nil>

OptimizedImage.where(upload_id: 20504).where(version: 2)

=> [#<OptimizedImage:0x000056366a01c1a0
  id: 95962,
  sha1: "5a32b5cc3e6f5c58d88a3c92a23076980a8ce840",
  extension: ".jpeg",
  width: 200,
  height: 200,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg",
  filesize: 28916,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a0741e8
  id: 95942,
  sha1: "ee353c9e23511b471e1a59c1f71a2ded3e366b1e",
  extension: ".jpeg",
  width: 20,
  height: 20,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_20x20.jpeg",
  filesize: 1270,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074120
  id: 95943,
  sha1: "944fa9fc542a79a5c50394c75022bf84ace297e5",
  extension: ".jpeg",
  width: 30,
  height: 30,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_30x30.jpeg",
  filesize: 1952,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074058
  id: 95944,
  sha1: "983490e58bed58c971ffa44e440b02ce3ea72bba",
  extension: ".jpeg",
  width: 40,
  height: 40,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_40x40.jpeg",
  filesize: 2695,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a07bf60

그러니까 겉보기에는 이미지가 있는 것 같은데, 표시가 되지 않습니다. 그냥 회색 기본 아바타 플레이스홀더만 보입니다.

DB 레코드 수준에서는 모두 정상적으로 보입니다. 문제를 조사할 때 상위 레벨로 이동해 보세요.

열거한 업로드의 URL을 수동으로 따랐을 때 어떤 결과가 나오나요?

Discourse URL 뒤에 /uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg를 붙이면(예를 들어) 404 Not Found 오류가 발생합니다.

그러면… 존재하지 않는 건가요? (희망을 갖고 물어봅니다 :stuck_out_tongue: )

/uploads/default/optimized뿐 아니라 /uploads/default/original의 파일 URL도 확인해 보세요.

404 … 이는 파일 시스템에서 /var/discourse/shared/standalone 안의 uploads 폴더를 확인하고, 실제 기존 파일(존재하는 경우)이 어디에 있는지 찾아봐야 한다는 뜻입니다. 파일을 찾으면 정상적으로 동작하는 새로 업로드된 파일의 위치와 비교해 보세요.

수동으로 백업에서 복구할 수도 있습니다.

설명해 주셔서 감사합니다.

방금 들어가서 다시 확인해 봤는데, 나열된 경로 중 일부는 존재하지 않습니다.

이상한 점은, 새로운 파일을 업로드하려는 사람들이 있는데, 그 새 파일들도 작동하지 않는다는 것입니다. 주신 명령어로 확인해 보면, 이 또한 존재하지 않는 경로가 보입니다. Discourse는 이걸 어떻게 "매핑"하는 건가요? 파일이 없다는 것(백업이 파일을 가져와야 했는데)은 어느 정도 이해가 되지만, 새 업로드가 유령 경로로 향한다는 건 좀 이해가 안 됩니다.

uploads 폴더 안의 tombstone 폴더를 확인해 보세요 - 누락된 파일 중 일부가 그곳에 있나요?

uploads 폴더 안에서 볼 수 있는 유일한 폴더는 default입니다… tombstone 폴더는 비활성화된 파일 등을 위한 용도인가요?

그리고 추가 정보 하나: 사용자가 이미 가지고 있던 동일한 이미지를 다시 업로드하려고 하면(파일 이름을 변경하더라도, 제가 확인한 쿼리들이 해시를 기반으로 하는 것으로 보아) 이미지가 로드되지 않고 빈 상태로 표시되며, 저장하면 회색 플레이스홀더가 보인다는 것을 알게 되었습니다.

아마도 이미지를 어떻게든 수정하면(Photoshop에서 다른 형식으로 저장하는 것만으로도) 다시 업로드할 수 있는 것 같습니다.

이는 정상적인 동작입니다. 중복 이미지를 방지하기 위해 데이터 파일의 해시가 데이터베이스에 저장됩니다.

컴포즈 에디터를 통해 이미지를 업로드하면 어떻게 되나요? 업로드가 완료되나요? 미리보기 영역에 표시되나요?

메시지를 작성하면서 이미지를 포함하면 미리보기 패널에 표시되고 업로드가 완료되는 것이 정상적인 동작입니다.

그렇다면 정확히 어떤 시점에 그 이미지가 표시되지 않게 되는 것인가요?

그 이미지의 URL을 확인하고 파일 시스템까지 추적해 보세요.

작동하지 않는 이미지의 URL(브라우저의 웹 개발자 도구를 통해)을 확인해 보세요. 차이점이 무엇인가요?

아마도 서로 다른 도메인을 가리키고 있는 것일 수 있습니다..

첫 번째 메시지에서는 구체적으로 아바타(사용자 프로필을 통한)를 의미했고, 두 번째는 에디터에 관한 것이었습니다.

즉, 일반 메시지에서는 드래그 앤 드롭을 하거나 “이미지 업로드” 버튼을 누르면 평소처럼 완벽하게 작동합니다.

요약하면 다음과 같습니다:

  • 아바타가 표시되지 않고, 플레이스홀더만 보입니다.
  • 커스텀 이모지도 표시되지 않습니다.
  • 사이트 이미지(로고 등)도 표시되지 않았습니다.
  • 작성기(composer)에서 이미지를 업로드하면 정상적으로 작동합니다.
  • 사고 발생 전에 사용하던 동일한 아바타를 업로드하려고 하면 작동하지 않습니다. 동작은 다음과 같습니다: 업로드는 진행되지만, 기본 문자, 그라바바 또는 업로드를 선택하는 상자에서 빈 사각형으로 표시됩니다. 선택을 확인하고 페이지가 새로 고침되면 회색 플레이스홀더가 표시됩니다.

또한:

  • Tombstone 폴더가 없습니다.
  • 이전 이미지들은 (제가 제공한 쿼리로 확인한 바와 같이) 존재하지 않는 디렉토리에 있습니다.

도메인 문제를 확인해 보겠습니다. 참고로, 정보를 조사하던 중 다음을 시도해 보았습니다:

  • Sidekiq에서 CreateMissingAvatars 작업을 트리거 → 성공하지 못함.
  • 모든 게시물을 다시 생성(Rebake) (좀 무리한 시도이지만) → 성공하지 못함.
  • 이 스레드를 기반으로, 메인 사이트가 오프라인 상태일 때 백업에서 복원하는 테스트를 위해 다른 도메인(실제로는 서브도메인)을 사용했기 때문에 일부 URL이 잘못되었을 수도 있다고 생각하여 다음을 실행했습니다: discourse remap talk.foo.com talk.bar.com → 성공하지 못함.

@Iceman

이것은 대부분 참고용(FYI)이며, 다소 과정보다 많은 정보(TMI)일 수도 있지만, 동시에 세 개의 컨테이너(웹 애플리케이션 2개와 데이터 컨테이너 1개)를 실행할 때 우리가 경험하는 흥미로운 현상들(그리고 이것이 사용자 아바타에 미치는 영향)에 대해 조금이라도 통찰을 얻을 수 있는 데 도움이 될 수 있습니다.

Redis / Sidekiq 작업 스케줄러가 병렬로 실행되지만, 사용자 웹 측에서는 단 하나만 "활성 상태"일 때 어떻게 작동하는지는 매우 흥미롭고(제 생각에는 정말 멋집니다), 다음과 같습니다:

실제 사례를 포함한 이 짧은 토론이 흥미롭기를 바랍니다. 이는 우리의 구성에 기반한 Discourse 작업 스케줄러, 이미지 최적화, 아바타에 대해 약간의 통찰을 제공할 수 있습니다:

Discourse가 Redis / Sidekiq를 사용하여 백그라운드 작업을 스케줄링하는 방식을 매우 좋아합니다. 그리고 이는 Discourse 소프트웨어 아키텍처의 핵심 강점이자 이점 중 하나라고 생각합니다.

참고: 이러한 개념은 백업 및 복원 과정의 다른 단계 및 다른 프로세스(시간 의존적)에도 다양한 미묘한 방식으로 적용되므로, Sidekiq가 백그라운드에서 작업을 스케줄링하는 방식과 이유를 이해하는 것이 좋습니다.

@neounix 님, 정보 주셔서 감사합니다. Discourse의 내부 구조를 "Rails를 배워서 도움을 주고 싶은데, 제 인스톨레이션을 고치려다 보니 학습 곡선이 너무 가파르네요"라는 관점에서 더 잘 이해하는 데 큰 도움이 됩니다. :stuck_out_tongue:

현재는 Redis/Sidekiq에 집중하여 일부 임베드가 작동하지 않는 이유를 파악하려 하고 있습니다. 제 생각에는 이것이 "Bake"와 관련이 있을 수 있지만, 디버깅 단계에서 아직 충분히 도달하지 못했기 때문에(희망적으로) 그 이유를 확신할 수는 없습니다.

여기서 제가 겪고 있는 문제에 대해서는 @Overgrow 님 덕분에 다음을 확인할 수 있었습니다:

  • 실제로 백업 프로세스는 파일들을 백업에 복사하긴 했지만, Discourse 인스톨레이션으로 복원하지는 않았습니다. 다른 세 가지 문제의 상태와/또는 수정 사항에 따라, 다른 인스톨레이션에서 다른 백업을 복구하여 백업 프로세스를 다시 테스트해야 할 수도 있지만, 아직 이것이 모든 사람에게 해당되는 문제인지 알 수 없습니다.

  • 그 때문에 이상한 동작이 발생하고 있었습니다.

  • 결국 백업을 열어 누락된 파일들을 인스톨레이션에 주입했습니다. Rebaking 없이 모든 것이 복구되었습니다.

그러나 다른 문제들은 여전히 남아 있습니다(데이터 컨테이너를 재빌드할 수 없는 문제, 이 부분은 전혀 감이 오지 않으며, Sidekiq와 이벤트에 집중하고 있는 두 가지 문제입니다. 이렇게 하면 해결될 수 있을 것 같아서요: 일부 원박스(특히 YouTube)가 작동하지 않는 문제와, 실제 편집이 없었음에도 일부 사용자에게 “잘못된” 편집이 반복적으로 발생하는 알림 문제. 따라서 저는 새로운 인스톨레이션의 이벤트에 어떤 문제가 있는 것 같아 파악 중입니다. :man_shrugging:)