S3 스토리지를 어떻게 끄나요?

여러분 안녕하세요,

AWS S3 스토리지를 완전히 끄고, S3 스토리지에 있는 모든 파일과 백업을 EC2 서버로 다시 가져오는 방법은 무엇인가요?

이렇게 하면 해결될 것 같습니다:

./launcher enter app
rake uploads:migrate_from_s3
rake posts:rebake

이 명령은 업로드 파일을 S3에서 웹 서버로 마이그레이션합니다. 그런 다음 app.yml 파일로 돌아가 DISCOURSE_USE_S3: false로 변경하고 다시 빌드하세요.

또한 Discourse의 관리자 영역에 들어가서 S3 모드를 활성화하는 모든 옵션의 체크를 해제하겠습니다.

@AntiMetaman님이 말씀하신 대로 해봤는데, rake aborted 오류가 발생합니다. 먼저 S3 업로드를 끄라고 해서 S3 업로드를 끄고 다시 rake를 실행했는데, 이번에는 이 오류가 뜹니다.

root@ip-172-31-7-247-app:/var/www/discourse# rake uploads:migrate_from_s3 --trace
** Invoke uploads:migrate_from_s3 (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `downcase' for nil:NilClass
/var/www/discourse/app/models/global_setting.rb:107:in `s3_bucket_name'
/var/www/discourse/app/models/site_setting.rb:157:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <main>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `block in execute'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:281:in `execute'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.6.0/monitor.rb:235:in `mon_synchronize'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/task.rb:188:in `invoke'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:160:in `invoke_task'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block (2 levels) in top_level'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:116:in `block in top_level'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:125:in `run_with_threads'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:110:in `top_level'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:83:in `block in run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:186:in `standard_exception_handling'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rake-13.0.1/lib/rake/application.rb:80:in `run'
bin/rake:13:in `<top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:24:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:46:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/friendly_errors.rb:123:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3

이거 맞죠?

s3

오늘 이 주제를 알게 되었습니다. 가능하시다면 잠시 기다리시는 것이 좋을 수도 있습니다.

관리자 패널에서만 S3를 끄면 사이트 수준에서만 비활성화됩니다. 전역적으로 비활성화하려면 app.yml에서 값을 true에서 false로 변경한 후 다시 빌드해야 합니다.

S3를 올바르게 설정하면 작동해야 합니다. 방금 migrate_from_s3와 migrate_to_s3를 시도해 보았는데 제 환경에서는 정상적으로 작동하며 오류가 발생하지 않았습니다. 이 오류가 무엇을 의미하는지 모르므로, 이 시점에서는 Discourse 개발자의 도움이 필요합니다:

NoMethodError: undefined method downcase’ for nil:NilClass`

아래에 작성했던 내 답변이 삭제된 것 같아 다시 올립니다.

이 오류는 문자열 메서드가 nil 객체에 대해 호출될 때 발생하며, 일반적으로 Ruby에서 문자열 객체가 예상되었는데 실제로는 nil인 경우 발생합니다.

그래서 그 오류가 발생하는 것입니다.

DISCOURSE_USE_S3: false를 app.yml에 추가했지만 여전히 같은 오류가 발생합니다. 어떤 버전의 Discourse를 사용 중이신가요? 저는 최신 버전을 사용 중입니다.

저도 최신 버전을 사용하고 있습니다. 재빌드 시 오류가 발생했나요? 만약 그렇다면, 해당 오류를 공유해 주시겠습니까?

아니요, 어떤 오류도 발생하지 않았습니다.

오류가 rake 명령어 실행 후에만 발생한다면, 정확히 무엇을 입력했는지 게시해 주실 수 있나요? 처음 S3를 설정했을 때, S3로 파일을 마이그레이션해야 하지 않았나요?

다음은 내 전체 app.yml 파일입니다.

## 이 파일은 올인원, 독립형 Discourse Docker 컨테이너 템플릿입니다.
##
## 이 파일을 변경한 후에는 반드시 다시 빌드해야 합니다.
## /var/discourse/launcher rebuild app
##
## 편집할 때 *매우* 주의하세요!
## YAML 파일은 공백이나 정렬 실수에 대해 매우 민감합니다!
## 필요 시 http://www.yamllint.com/에서 이 파일을 검증하세요

templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
## Lets Encrypt(https)를 추가하려면 아래 두 줄의 주석을 해제하세요
  - "templates/web.ssl.template.yml"
  - "templates/web.letsencrypt.ssl.template.yml"
##  - "templates/cloudflare.template.yml"

## 이 컨테이너가 어떤 TCP/IP 포트를 노출해야 합니까?
## Apache나 nginx 같은 다른 웹서버와 포트를 공유하려면
## https://meta.discourse.org/t/17247 에서 자세한 내용을 확인하세요
expose:
  - "80:80"   # http
  - "443:443" # https

params:
  db_default_text_search_config: "pg_catalog.english"

  ## db_shared_buffers는 총 메모리의 최대 25%로 설정하세요.
  ## 감지된 RAM 기반으로 bootstrap이 자동으로 설정하거나, 직접 오버라이드할 수 있습니다.
  db_shared_buffers: "128MB"

  ## 정렬 성능을 향상시킬 수 있지만, 연결당 메모리 사용량이 증가합니다.
  #db_work_mem: "40MB"

  ## 이 컨테이너가 어떤 Git 리비전을 사용해야 합니까? (기본값: tests-passed)
  #version: tests-passed

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## 동시에 몇 개의 웹 요청을 지원할 수 있습니까? 메모리와 CPU 코어 수에 따라 달라집니다.
  ## 감지된 CPU 기반으로 bootstrap이 자동으로 설정하거나, 직접 오버라이드할 수 있습니다.
  UNICORN_WORKERS: 2

  ## TODO: 이 Discourse 인스턴스가 응답할 도메인 이름
  DISCOURSE_HOSTNAME: engineersasylum.com

  ## 컨테이너가 위에서 지정한 도메인 이름(-h 옵션)과 동일한 이름으로 시작되도록 하려면 주석을 해제하세요
  ## (기본값 "$hostname-$config")
  #DOCKER_USE_HOSTNAME: true

  ## TODO: 초기 가입 시 관리자 및 개발자로 설정될 쉼표로 구분된 이메일 목록
  ## 예: 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'praveen369gen@gmail.com'

  ## TODO: 새 계정을 검증하고 알림을 보내는 데 사용되는 SMTP 메일 서버
  DISCOURSE_SMTP_ADDRESS: email-smtp.us-east-1.amazonaws.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: AXXXXXXXXXXXXXXX
  DISCOURSE_SMTP_PASSWORD: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  #DISCOURSE_SMTP_ENABLE_START_TLS: true           # (선택 사항, 기본값 true)

  ## Lets Encrypt 템플릿을 추가했다면, 무료 SSL 인증서를 받으려면 아래 주석을 해제하세요
  LETSENCRYPT_ACCOUNT_EMAIL: praxxxxxx@gmail.com

  ## 이 Discourse 인스턴스의 CDN 주소 (추출하도록 구성됨)
  ## 자세한 내용은 https://meta.discourse.org/t/14857 을 참조하세요
  #DISCOURSE_CDN_URL: //discourse-cdn.example.com
  DISCOURSE_USE_S3: false

## Docker 컨테이너는 상태가 없으며, 모든 데이터는 /shared에 저장됩니다.
volumes:
  - volume:
      host: /var/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /var/discourse/shared/standalone/log/var-log
      guest: /var/log

## 플러그인은 여기에 추가합니다.
## 자세한 내용은 https://meta.discourse.org/t/19157 을 참조하세요
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-adplugin.git
          - git clone https://github.com/communiteq/discourse-sitemap.git
          - git clone https://github.com/discourse/discourse-whos-online.git
          - git clone https://github.com/discourse/discourse-push-notifications.git
          - git clone https://github.com/discourse/discourse-chat-integration.git
          - git clone https://github.com/davidtaylorhq/discourse-telegram-notifications.git
          - git clone https://github.com/discourse/discourse-knowledge-explorer.git
          - git clone https://github.com/discourse/discourse-math.git

## 빌드 후 실행할 모든 사용자 정의 명령
run:
  - exec: echo "Beginning of custom commands"
  ## 첫 번째 가입 시 'From' 이메일 주소를 설정하려면 주석을 해제하고 변경하세요:
  ## 첫 번째 가입 이메일을 받은 후, 해당 줄을 다시 주석 처리하세요. 한 번만 실행하면 됩니다.
  #- exec: rails r "SiteSetting.notification_email='info@unconfigured.discourse.org'"
  - exec: echo "End of custom commands"

정확히 기억은 나지 않지만, rake uploads:migrate_to_s3를 사용하여 S3로 마이그레이션한 것 같습니다.

정확한 원인은 모르겠지만, 같은 오류가 발생한 유사한 스레드가 있습니다:

팀 구성원과 확인해 보시는 것이 좋을 것 같습니다.

@Pravi 님, 안녕하세요.

부수적인 질문이 있습니다:

yml
게시글에서 다음과 같이 "말씀"하셨죠:

DISCOURSE_SMTP_PASSWORD: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

이것이 올바른가요? yml 파일에서 비밀번호가 이중 인용부호로 감싸져 있나요?

네, 이중 따옴표로 되어 있습니다. 2년 전에 추가한 이후로 변경한 적이 없습니다.

이중 따옴표를 제거한 후 앱을 다시 빌드했습니다. 그런 다음 rake uploads:migrate_from_s3를 다시 실행해 보았지만 여전히 문제가 해결되지 않았습니다. 동일한 오류가 발생합니다.

안녕하세요, @Pravi

솔직히 AWS와 S3에 대한 반감(anti-fan)이 있어 사용하지 않습니다.

Rake 태스크를 살펴보고 해당 스크립트를 역공학한 뒤, 태스크를 단계별로 수동으로 수행하는 방법을 고려해 보셨나요?

디스코urs의 내부 스크립트에 대해 잘 모르겠고, 스크립트를 수정하는 것이 조금 두렵습니다. 모든 것을 망치고 싶지 않거든요.

discourse.config 파일의 위치를 알려주실 수 있나요? 서버 어디에서도 찾을 수 없습니다. find 명령어로는 아무것도 반환되지 않습니다.

root@ip-172-31-7-247:/var/discourse# find . -name "*.config"
root@ip-172-31-7-247:/var/discourse# find . -name "*.conf"
./shared/standalone/letsencrypt/engineersasylum.com/engineersasylum.com.conf
./shared/standalone/letsencrypt/engineersasylum.com/engineersasylum.com.csr.conf
./shared/standalone/letsencrypt/engineersasylum.com_ecc/engineersasylum.com.conf
./shared/standalone/letsencrypt/engineersasylum.com_ecc/engineersasylum.com.csr.conf
./shared/standalone/letsencrypt/ca/acme-v01.api.letsencrypt.org/ca.conf
./shared/standalone/letsencrypt/ca/acme-v02.api.letsencrypt.org/ca.conf
./shared/standalone/letsencrypt/account.conf
./shared/standalone/postgres_data/pg_hba.conf
./shared/standalone/postgres_data/postgresql.auto.conf
./shared/standalone/postgres_data/pg_ident.conf
./shared/standalone/postgres_data/postgresql.conf
root@ip-172-31-7-247:/var/discourse#

@Pravi 님, 안녕하세요.

잘못 이해하신 것 같아 죄송합니다.

저는 그 파일이나 다른 어떤 파일을 편집해 달라고 요청한 적이 없습니다.

제 생각에 스크립트를 "역공학(Reverse engineer)"한다는 것은 그 스크립트를 연구하고 작동 방식을 살펴보는 것을 의미하며, 파일 편집과는 아무런 상관이 없습니다. 즉, 읽어서 이해하는 것을 뜻합니다.

보통 에러를 유발하는 스크립트나 파일을 읽고 이해하게 되면, 문제를 어떻게 해결해야 하는지 파악할 수 있게 됩니다.

현재 에러 메시지를 보고 계신 파일은 읽어보지 않으신 것 같습니다.

도움이 되셨으면 좋겠습니다.

말씀하신 뜻을 이해했습니다. 해보겠습니다.
‘discourse.config’ 파일의 위치를 알려 주실 수 있나요? S3 설정은 어디에 저장되어 있나요?