오케이, Claude와 많은 칭찬으로 문제를 해결했습니다. 비슷한 또는 동일한 문제를 겪고 있는 다른 분들을 도우려고 제가 한 작업을 공유합니다.
이것이 가장 지능적이고 최적의 방법인지는 확실하지 않지만, 제게는 효과가 있었던 방법입니다.
전문가가 아니라 항상 배우고 있는 초보자이므로 주의하시고 이 점을 염두에 두시기 바랍니다.
문제 (S3 → 로컬 파일 시스템)
AWS S3에서 로컬 FS로 마이그레이션한 후, 많은 이미지들이 transparent.png로 표시되었습니다. 파일은 항상 디스크에 존재했지만 Discourse가 이를 해결하지 못했습니다.
근본 원인은 끊어진 체인이었습니다:
upload://짧은 URL(base62 인코딩된 SHA1)을 가진 게시물.- SHA1 → 로컬 파일 경로를 매핑하는 데이터베이스의
uploads. - SHA1 해시로 이름이 지정된 파일을 저장하는 파일 시스템.
마이그레이션은 파일을 디스크에 올바르게 이동했지만, uploads DB 기록이 존재하지 않았습니다. 일치하는 기록이 없으면 Discourse는 transparent.png로 대체합니다.
해결책 (기록 생성 및 재베이크)
# 컨테이너 진입
./launcher enter app
rails c
고아 파일에서 누락된 업로드 기록 생성:
dir = Rails.root.join("public", "uploads", "default", "original")
created = 0
Dir.glob(dir.join("**", "*")).select { |f| File.file?(f) }.each do |path|
sha = File.basename(path, File.extname(path))
next if Upload.find_by(sha1: sha)
ext = File.extname(path).delete(".")
relative = path.sub("#{Rails.root}/public", "")
u = Upload.new
u.sha1 = sha
u.url = relative
u.original_filename = File.basename(path)
u.filesize = File.size(path)
u.extension = ext
u.user_id = -1
u.save!(validate: false)
created += 1
puts "Created upload #{u.id}: #{sha}"
end
puts "Total created: #{created}"
복원된 업로드를 참조하는 게시물 재베이크:
fixed_posts = 0
Upload.where(user_id: -1).find_each do |u|
short = u.short_url
next unless short
Post.where("raw LIKE '%upload://%'").find_each do |p|
urls = p.raw.scan(/upload:\/\/[^\s\]\)]+/)
urls.each do |url|
decoded = Upload.sha1_from_short_url(url)
if decoded == u.sha1
p.rebake!
fixed_posts += 1
puts "Rebaked post #{p.id}"
break
end
end
end
end
puts "Total rebaked: #{fixed_posts}"
누락된 최적화 파일 재생성:
원본 파일을 수정한 후, 최적화 파일(1X, 2X 등)을 채워 넣어야 합니다.
Rake는 discourse 컨테이너에서는 작동하지만 rails 콘솔에서는 작동하지 않습니다.
rake uploads:regenerate_missing_optimized
[선택 사항] 여전히 최적화 파일이 누락된 경우
rake uploads:regenerate_missing_optimized가 모든 파일 문제를 해결하지 못하고 여전히 파일이 누락된 경우:
# 컨테이너 진입
./launcher enter app
rails c
missing = 0
OptimizedImage.find_each do |oi|
path = "#{Rails.root}/public#{oi.url}"
unless File.exist?(path)
missing += 1
oi.delete
end
end
puts "Deleted #{missing} broken optimized records"
그 후 rails를 종료하고 다시 실행합니다:
rake uploads:regenerate_missing_optimized
안전한 롤백 (만약을 대비하여)
생성된 모든 기록은 user_id: -1을 사용하며, delete_all은 콜백을 건너뛰므로 파일 시스템의 파일에는 영향을 미치지 않습니다. 되돌리려면:
Upload.where(user_id: -1).delete_all
실수로
destroy_all을 사용하여 파일이 톰스톤으로 이동하는 콜백이 트리거되었습니다.테스트용으로 사용했던 개별 항목을 복구하고 제 접근 방식을 재구성했습니다.