분리된 Discourse 애플리케이션 - 관리형 Redis, 관리형 Postgres 및 Digital Ocean 볼륨을 사용한 Discourse

Digital Ocean의 Managed Redis Database에 Discourse를 연결하려고 합니다. Digital Ocean의 Managed Postgres Database로 Postgres는 정상적으로 설정했지만, Redis는 오류가 발생합니다. 이 문제에 대해 어떻게 생각하시나요?

    templates:
      - templates/web.template.yml
      - templates/web.ssl.template.yml
    # 'links' 키를 사용하여 컨테이너를 연결합니다. (Docker --link 플래그 사용)
    expose:
      - '80:80'
      - '443:443'
    params:
      db_default_text_search_config: pg_catalog.english
      db_shared_buffers: 512MB
    env:
      LANG: en_US.UTF-8
      UNICORN_WORKERS: 8
    
      # https://github.com/discourse/discourse/blob/master/config/discourse_defaults.conf
      DISCOURSE_HOSTNAME: blah.example.com
      DISCOURSE_DEVELOPER_EMAILS: email@example.com
      DISCOURSE_SMTP_ADDRESS: smtp.mailgun.org
      DISCOURSE_SMTP_PORT: 587
      DISCOURSE_SMTP_USER_NAME: blah@mail.com
      DISCOURSE_SMTP_PASSWORD: 9cd16e-aff2d1b9-36c86fff
      DISCOURSE_DB_NAME: defaultdb
      DISCOURSE_DB_USERNAME: doadmin
      DISCOURSE_DB_PASSWORD: gp5m224
      DISCOURSE_DB_HOST: private-digitalocean-stage-discuss-postgres-do-user-.ondigitalocean.com
      DISCOURSE_DB_PORT: 25060
      DISCOURSE_REDIS_USERNAME: default
      DISCOURSE_REDIS_PASSWORD: dex3mf
      DISCOURSE_REDIS_HOST: private-digitalocean-stage-discuss-redis-do-user-966537-0.b.db.ondigitalocean.com
      DISCOURSE_REDIS_PORT: 25061
      DISCOURSE_REDIS_CLIENT_ID: ~
    volumes:
      - volume:
          host: /var/discourse/shared/standalone
          guest: /shared
      - volume:
          host: /var/discourse/shared/standalone/log/var-log
          guest: /var/log
    hooks:
      after_code:
        - exec:
            cd: $home/plugins
            cmd:
              - 'git clone https://github.com/discourse/docker_manager.git'
    run:
      - exec: echo "Beginning of custom commands"
      - exec: echo "End of custom commands"

여기서 다음 내용을 추가했습니다:

  DISCOURSE_REDIS_USERNAME: default
  DISCOURSE_REDIS_PASSWORD: dex3mf
  DISCOURSE_REDIS_HOST: private-digitalocean-stage-discuss-redis-do-user-.db.ondigitalocean.com
  DISCOURSE_REDIS_PORT: 25061
  DISCOURSE_REDIS_CLIENT_ID: ~

하지만 다음과 같은 오류가 발생합니다:

  I, [2021-02-13T04:05:48.508236 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
  Failed to report error: Connection lost (ECONNRESET) 2 Connection lost (ECONNRESET) subscribe failed, reconnecting in 1 second. Call stack /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:275:in `rescue in io'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:267:in `io'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:279:in `read'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:131:in `block in call'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:248:in `block (2 levels) in process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:389:in `ensure_connected'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:238:in `block in process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:325:in `logging'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:237:in `process'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:131:in `call'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:113:in `block in connect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:313:in `with_reconnect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:111:in `connect'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:294:in `with_socket_timeout'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/client.rb:144:in `call_loop'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/subscribe.rb:44:in `subscription'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis/subscribe.rb:14:in `subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:3507:in `_subscription'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:2326:in `block in subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:69:in `block in synchronize'
    /usr/local/lib/ruby/2.7.0/monitor.rb:202:in `synchronize'
    /usr/local/lib/ruby/2.7.0/monitor.rb:202:in `mon_synchronize'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:69:in `synchronize'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/redis-4.2.5/lib/redis.rb:2325:in `subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus/backends/redis.rb:287:in `global_subscribe'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus.rb:766:in `global_subscribe_thread'
    /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/message_bus-3.3.4/lib/message_bus.rb:714:in `block in new_subscriber_thread'
    rake aborted!

얼마 전 Digital Ocean의 모든 관리형 서비스와 호환되도록 작업했습니다. 당시 Digital Ocean의 Redis에는 SSL이 필수였는데, 우리는 그때 이를 지원하지 않았습니다.

Digital Ocean의 Redis를 사용하려면 다음을 사용하세요.

  DISCOURSE_REDIS_HOST: falcoland-redis-do-user-435229-0.a.db.ondigitalocean.com
  DISCOURSE_REDIS_PASSWORD: vp39d0dpy8dxn68n
  DISCOURSE_REDIS_PORT: 25061
  DISCOURSE_REDIS_USE_SSL: true

@Falco 감사합니다 ~~ 작동합니다!!!

다음 단계는 /var/discourse를 Discourse 애플리케이션 서버들이 공유할 수 있는 Digital Ocean 볼륨으로 이동하는 것입니다. 볼륨을 마운트하고 디렉터리에 심볼릭 링크를 만드는 방식으로 진행하면 될까요?

목표 아키텍처는 로드 밸런서 → DO Redis와 Postgres를 사용하는 여러 Discourse 서버, 그리고 각 서버마다 별도의 볼륨을 두지 않고 여러 Discourse 서버가 함께 공유하는 단일 DO 볼륨을 구성하는 것입니다.

어떻게 생각하시나요?

왜 그렇게 하시려는 건가요?

Using Object Storage for Uploads (S3 & Clones)에 따라 모든 정적 자산과 사용자 업로드를 Digital Ocean Spaces에 두면, 애플리케이션 서버 간에 아무것도 공유할 필요가 없습니다.

다만 여러 애플리케이션 드롭렛, 관리형 Redis, PostgreSQL 및 객체 스토리지를 사용하면 가격이 우리의 관리형 호스팅과 매우 비슷해집니다. :wink:

감사합니다. 제 포럼은 프론트엔드 템플릿을 사용하지 않습니다. NodeJS로 API를 구축했고, 프론트엔드는 VueJS를 사용하고 있습니다. 따라서 저는 discourse를 데이터 공유와 저장에만 사용하고 있습니다. 또한 포럼에서 이미지 업로드를 허용하지 않습니다.

제 사용 사례는 다음과 같습니다. 로드 밸런서 뒤에서 모든 discourse 애플리케이션 서버가 하나의 파일 볼륨을 공유하는 것입니다. 이제 /var/discourse 볼륨을 제외한 모든 구성 요소가 분리되었습니다. 이해가 되시나요?

hey @Falco, 쉽게 해결했어요:

먼저 DO에서 볼륨을 생성하고, DO 단계에서 드롭렛을 해당 볼륨에 연결한 다음,
discourse 머신에 ssh로 접속하세요.

mv /var/discourse /var/discourse.bak
mkdir /home/discourse
mount /dev/sda /home/discourse
mv /var/discourse.bak/* /home/discourse
nano /home/discourse/containers/app.yml

volumes 섹션을 업데이트하세요:

volumes:
  - volume:
      host: /home/discourse/shared/standalone
      guest: /shared
  - volume:
      host: /home/discourse/shared/standalone/log/var-log
      guest: /var/log

그리고,

cd /home/discourse
sudo ./launcher rebuild app

이제 discourse가 볼륨에서 서빙됩니다. 모든 부분이 이제 분리(decoupled)되었으므로 스냅샷을 찍을 수 있고 로드 밸런서 뒤에 배포할 수 있습니다.

감사합니다!