Aplicação Discourse Desacoplada - Redis Gerenciado, Postgres Gerenciado e Volume Digital Ocean com Discourse

Estou tentando conectar o Discourse ao Redis no Banco de Dados Gerenciado Redis da Digital Ocean. Consegui fazer o PostgreSQL funcionar perfeitamente com o Banco de Dados Gerenciado PostgreSQL da Digital Ocean, mas o Redis está me dando um erro. O que você pode concluir com isso?

    templates:
      - templates/web.template.yml
      - templates/web.ssl.template.yml
    # Use a chave 'links' para vincular contêineres, ou seja, use a flag 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 "Início dos comandos personalizados"
      - exec: echo "Fim dos comandos personalizados"

Veja aqui, adicionei:

  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: ~

Mas recebi este erro:

  I, [2021-02-13T04:05:48.508236 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
  Falha ao relatar erro: Conexão perdida (ECONNRESET) 2 Conexão perdida (ECONNRESET) assinatura falhou, reconectando em 1 segundo. Stack de chamada /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!

Trabalhei para garantir nossa compatibilidade com todos os serviços gerenciados do Digital Ocean algum tempo atrás. O Redis deles exige SSL obrigatório, o que não era suportado na época.

Para fazer o Redis deles funcionar, use:

  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
4 curtidas

Obrigado, @Falco ~~ funciona!!!

Meu próximo passo é mover o /var/discourse para um volume do Digital Ocean que os servidores de aplicação do Discourse possam compartilhar. Você apenas montaria o Volume e criaria links simbólicos para os diretórios?

Minha arquitetura alvo é Balanceador de Carga → múltiplos servidores Discourse com Redis e PostGres do DO, e um volume compartilhado do DO que os múltiplos servidores Discourse compartilham, em vez de terem seus próprios volumes.

O que você acha?

Por quê?

Coloque todos os ativos estáticos e uploads de usuários no Digital Ocean Spaces seguindo Usando Armazenamento de Objetos para Uploads (S3 e Clones) e seus servidores de aplicação não precisarão compartilhar nada.

Uma coisa a ter em mente é que, com múltiplos droplets de aplicação, Redis gerenciado, PostgreSQL e Armazenamento de Objetos, o preço fica bem próximo ao do nosso hospedagem gerenciada :wink:

4 curtidas

Obrigado. Meu fórum não utiliza os templates de frontend. Tenho uma API construída em NodeJS e o frontend é em VueJS. Portanto, estou usando o Discourse apenas para compartilhar e armazenar dados. Não permito upload de imagens no meu fórum.

Então, este é o meu caso de uso: todos os servidores de aplicação do Discourse podem compartilhar um único volume de arquivos atrás do balanceador de carga. Cada parte agora está desacoplada, exceto o volume /var/discourse. Faz sentido?

Olá @Falco, descobri isso bastante facilmente:

Primeiro, crie o volume no DO e certifique-se de vincular seu droplet a ele nas etapas do DO. Em seguida, acesse via SSH sua máquina Discourse:

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

Atualize a seção de volumes:

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

Depois:

cd /home/discourse
sudo ./launcher rebuild app

Agora seu Discourse é atendido a partir do volume, permitindo capturas de snapshot e implantação atrás de um balanceador de carga, já que todas as partes estão agora desacopladas.

Abraços!

2 curtidas