Discourse Bad Gateway após reinicialização

Meu servidor roda em uma Máquina Virtual hospedada por um dos principais provedores de nuvem.
Instalei com sucesso o discourse nele e ele tem funcionado bem no último mês.
Hoje, decidi alterar as especificações da minha VM de volta para sua configuração original(*) e reiniciei. Ao iniciar, embora tudo o mais no servidor esteja funcionando corretamente, estou recebendo um erro 502 Bad Gateway ao tentar acessar o fórum Discourse.
Pensando que a instância do Docker não tivesse iniciado automaticamente, fiz SSH no servidor e executei ./launcher start app, mas recebi uma mensagem dizendo que havia espaço insuficiente restante (5 GB disponíveis). Então, executei df -h, que indica que tenho na verdade 14 GB disponíveis. Assim, executei ./launcher start app novamente, mas desta vez recebi um aviso de que o Docker iria baixar arquivos e que eu deveria ter paciência. Após algum processamento, obtive a mensagem Nothing to do, your container has already started! (Nada a fazer, seu contêiner já foi iniciado!). No entanto, minhas tentativas de acessar o fórum ainda retornavam 502 Bad Gateway.
Depois de consultar este fórum aqui, decidi executar ./launcher rebuild app e obtive os seguintes erros, relacionados ao PostgreSQL:

    user@host:[16:48]:/var/discourse# ./launcher rebuild app
    Garantindo que o launcher está atualizado
    Buscando origem
    Launcher atualizado
    Parando o contêiner antigo
    + /usr/bin/docker stop -t 60 app
    app
    cd /pups && git pull && /pups/bin/pups --stdin
    Já está atualizado.
    I, [2020-07-01T07:19:42.821347 #1]  INFO -- : Carregando --stdin
    I, [2020-07-01T07:19:42.831806 #1]  INFO -- : > locale-gen $LANG && update-locale
    I, [2020-07-01T07:19:42.879007 #1]  INFO -- : Gerando locais (isso pode demorar um pouco)...
    Geração concluída.
    
    I, [2020-07-01T07:19:42.879431 #1]  INFO -- : > mkdir -p /shared/postgres_run
    I, [2020-07-01T07:19:42.885054 #1]  INFO -- :
    I, [2020-07-01T07:19:42.885734 #1]  INFO -- : > chown postgres:postgres /shared/postgres_run
    I, [2020-07-01T07:19:42.891657 #1]  INFO -- :
    I, [2020-07-01T07:19:42.892269 #1]  INFO -- : > chmod 775 /shared/postgres_run
    I, [2020-07-01T07:19:42.898103 #1]  INFO -- :
    I, [2020-07-01T07:19:42.898942 #1]  INFO -- : > rm -fr /var/run/postgresql
    I, [2020-07-01T07:19:42.905607 #1]  INFO -- :
    I, [2020-07-01T07:19:42.906463 #1]  INFO -- : > ln -s /shared/postgres_run /var/run/postgresql
    I, [2020-07-01T07:19:42.912617 #1]  INFO -- :
    I, [2020-07-01T07:19:42.913233 #1]  INFO -- : > socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres já está rodando, pare o contêiner ; exit 1
    2020/07/01 07:19:42 socat[26] E connect(6, AF=1 "/shared/postgres_run/.s.PGSQL.5432", 36): Arquivo ou diretório não encontrado
    I, [2020-07-01T07:19:42.925688 #1]  INFO -- :
    I, [2020-07-01T07:19:42.926081 #1]  INFO -- : > rm -fr /shared/postgres_run/.s*
    I, [2020-07-01T07:19:42.931174 #1]  INFO -- :
    I, [2020-07-01T07:19:42.931649 #1]  INFO -- : > rm -fr /shared/postgres_run/*.pid
    I, [2020-07-01T07:19:42.938154 #1]  INFO -- :
    I, [2020-07-01T07:19:42.938850 #1]  INFO -- : > mkdir -p /shared/postgres_run/12-main.pg_stat_tmp
    I, [2020-07-01T07:19:42.943575 #1]  INFO -- :
    I, [2020-07-01T07:19:42.944331 #1]  INFO -- : > chown postgres:postgres /shared/postgres_run/12-main.pg_stat_tmp
    I, [2020-07-01T07:19:42.949159 #1]  INFO -- :
    I, [2020-07-01T07:19:42.961190 #1]  INFO -- : Arquivo > /etc/service/postgres/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.973345 #1]  INFO -- : Arquivo > /etc/service/postgres/log/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.983929 #1]  INFO -- : Arquivo > /etc/runit/3.d/99-postgres  chmod: +x  chown:
    I, [2020-07-01T07:19:42.994843 #1]  INFO -- : Arquivo > /root/upgrade_postgres  chmod: +x  chown:
    I, [2020-07-01T07:19:42.995487 #1]  INFO -- : > chown -R root /var/lib/postgresql/12/main
    I, [2020-07-01T07:19:44.012812 #1]  INFO -- :
    I, [2020-07-01T07:19:44.013656 #1]  INFO -- : > [ ! -e /shared/postgres_data ] && install -d -m 0755 -o postgres -g postgres /shared/postgres_data && sudo -E -u postgres /usr/lib/postgresql/12/bin/initdb -D /shared/postgres_data || exit 0
    I, [2020-07-01T07:19:44.019545 #1]  INFO -- :
    I, [2020-07-01T07:19:44.019872 #1]  INFO -- : > chown -R postgres:postgres /shared/postgres_data
    I, [2020-07-01T07:19:44.064432 #1]  INFO -- :
    I, [2020-07-01T07:19:44.065186 #1]  INFO -- : > chown -R postgres:postgres /var/run/postgresql
    I, [2020-07-01T07:19:44.071385 #1]  INFO -- :
    I, [2020-07-01T07:19:44.072196 #1]  INFO -- : > /root/upgrade_postgres
    I, [2020-07-01T07:19:44.084004 #1]  INFO -- :
    I, [2020-07-01T07:19:44.084662 #1]  INFO -- : > rm /root/upgrade_postgres
    I, [2020-07-01T07:19:44.090399 #1]  INFO -- :
    I, [2020-07-01T07:19:44.092280 #1]  INFO -- : Substituindo data_directory = '/var/lib/postgresql/12/main' por data_directory = '/shared/postgres_data' em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.093969 #1]  INFO -- : Substituindo (?-mix:#?listen_addresses *=.*) por listen_addresses = '*' em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095204 #1]  INFO -- : Substituindo (?-mix:#?synchronous_commit *=.*) por synchronous_commit = $db_synchronous_commit em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095937 #1]  INFO -- : Substituindo (?-mix:#?shared_buffers *=.*) por shared_buffers = $db_shared_buffers em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.096695 #1]  INFO -- : Substituindo (?-mix:#?work_mem *=.*) por work_mem = $db_work_mem em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.097554 #1]  INFO -- : Substituindo (?-mix:#?default_text_search_config *=.*) por default_text_search_config = '$db_default_text_search_config' em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.101971 #1]  INFO -- : > install -d -m 0755 -o postgres -g postgres /shared/postgres_backup
    I, [2020-07-01T07:19:44.112672 #1]  INFO -- :
    I, [2020-07-01T07:19:44.113831 #1]  INFO -- : Substituindo (?-mix:#?max_wal_senders *=.*) por max_wal_senders = $db_max_wal_senders em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.114973 #1]  INFO -- : Substituindo (?-mix:#?wal_level *=.*) por wal_level = $db_wal_level em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.116047 #1]  INFO -- : Substituindo (?-mix:#?checkpoint_segments *=.*) por checkpoint_segments = $db_checkpoint_segments em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.117033 #1]  INFO -- : Substituindo (?-mix:#?logging_collector *=.*) por logging_collector = $db_logging_collector em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.118051 #1]  INFO -- : Substituindo (?-mix:#?log_min_duration_statement *=.*) por log_min_duration_statement = $db_log_min_duration_statement em /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.119352 #1]  INFO -- : Substituindo (?-mix:^#local +replication +postgres +peer$) por local replication postgres  peer em /etc/postgresql/12/main/pg_hba.conf
    I, [2020-07-01T07:19:44.120299 #1]  INFO -- : Substituindo (?-mix:^host.*all.*all.*127.*$) por host all all 0.0.0.0/0 md5 em /etc/postgresql/12/main/pg_hba.conf
    I, [2020-07-01T07:19:44.121038 #1]  INFO -- : > HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/12/bin/postmaster -D /etc/postgresql/12/main
    I, [2020-07-01T07:19:44.126334 #1]  INFO -- : > sleep 5
    2020-07-01 07:19:44.157 UTC [49] LOG:  iniciando PostgreSQL 12.2 (Debian 12.2-2.pgdg100+1) em x86_64-pc-linux-gnu, compilado por gcc (Debian 8.3.0-6) 8.3.0, 64-bit
    2020-07-01 07:19:44.158 UTC [49] LOG:  ouvindo no endereço IPv4 "0.0.0.0", porta 5432
    2020-07-01 07:19:44.158 UTC [49] LOG:  ouvindo no endereço IPv6 "::", porta 5432
    2020-07-01 07:19:44.161 UTC [49] LOG:  ouvindo no socket Unix "/var/run/postgresql/.s.PGSQL.5432"
    2020-07-01 07:19:44.162 UTC [49] FATAL:  não foi possível mapear memória compartilhada anônima: Não foi possível alocar memória
    2020-07-01 07:19:44.162 UTC [49] HINT:  Este erro geralmente significa que a solicitação do PostgreSQL por um segmento de memória compartilhada excedeu a memória disponível, espaço de swap ou páginas grandes. Para reduzir o tamanho da solicitação (atualmente 4423172096 bytes), reduza o uso de memória compartilhada do PostgreSQL, talvez reduzindo shared_buffers ou max_connections.
    2020-07-01 07:19:44.162 UTC [49] LOG:  sistema de banco de dados desligado
    I, [2020-07-01T07:19:49.141762 #1]  INFO -- :
    I, [2020-07-01T07:19:49.142221 #1]  INFO -- : > su postgres -c 'createdb discourse' || true
    createdb: erro: não foi possível conectar ao banco de dados template1: não foi possível conectar ao servidor: Arquivo ou diretório não encontrado
        O servidor está rodando localmente e aceitando
        conexões no socket Unix "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.227852 #1]  INFO -- :
    I, [2020-07-01T07:19:49.228226 #1]  INFO -- : > su postgres -c 'psql discourse -c "create user discourse;"' || true
    psql: erro: não foi possível conectar ao servidor: não foi possível conectar ao servidor: Arquivo ou diretório não encontrado
        O servidor está rodando localmente e aceitando
        conexões no socket Unix "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.330486 #1]  INFO -- :
    I, [2020-07-01T07:19:49.330822 #1]  INFO -- : > su postgres -c 'psql discourse -c "grant all privileges on database discourse to discourse;"' || true
    psql: erro: não foi possível conectar ao servidor: não foi possível conectar ao servidor: Arquivo ou diretório não encontrado
        O servidor está rodando localmente e aceitando
        conexões no socket Unix "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.425970 #1]  INFO -- :
    I, [2020-07-01T07:19:49.426356 #1]  INFO -- : > su postgres -c 'psql discourse -c "alter schema public owner to discourse;"'
    psql: erro: não foi possível conectar ao servidor: não foi possível conectar ao servidor: Arquivo ou diretório não encontrado
        O servidor está rodando localmente e aceitando
        conexões no socket Unix "/var/run/postgresql/.s.PGSQL.5432"?
    I, [2020-07-01T07:19:49.506638 #1]  INFO -- :
    I, [2020-07-01T07:19:49.507202 #1]  INFO -- : Encerrando processos assíncronos
    
    
    FALHA
    --------------------
    Pups::ExecError: su postgres -c 'psql discourse -c "alter schema public owner to discourse;"' falhou com retorno #<Process::Status: pid 75 exit 2>
    Localização da falha: /pups/lib/pups/exec_command.rb:112:in `spawn'
    exec falhou com os parâmetros "su postgres -c 'psql $db_name -c \"alter schema public owner to $db_user;\"'"
    eb41679f76cd749ccd8c84a7543365d093619b80df6fc6750b9349fb63565fa1
    ** FALHA NO BOOTSTRAP ** por favor, role para cima e procure mensagens de erro anteriores, pode haver mais de uma.
    ./discourse-doctor pode ajudar a diagnosticar o problema.
    user@host:[17:19]:/var/discourse#

Estranhamente, apesar dos erros acima, executar ./launcher start app não produz erros:

iniciando contêiner existente
+ /usr/bin/docker start app
app

Com a instância em execução, tentei usar ./launcher enter app para entrar no contêiner. (Na minha humilde opinião, as ferramentas disponíveis no contêiner são muito pobres (sim, sou usuário de nano e gosto de ter vários aliases mapeados; por exemplo, ll). Não consigo encontrar o caminho físico para as pastas dentro da instância do Docker (como gostaria de baixá-las usando um cliente FTP).

Em /var/log/nginx/error.log, tenho a seguinte entrada de erro para cada vez que atualizo meu navegador:

2020/07/01 07:44:16 [error] 646#646: *3 connect() falhou (111: Connection refused) ao conectar ao upstream, cliente: xxx.xx.0.1, servidor: _, solicitação: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3000/", host: "discourse.myDomain.com"

O que poderia ser a causa do meu problema? Por que o PostgreSQL de repente não está funcionando?

(*) Uma semana após instalar o Discourse, atualizei meu servidor com mais CPUs e memória. Eu precisava fazer isso para rodar uma videoconferência que hospedei. Com a conferência concluída, voltei à minha configuração normal. Observe que não alterei os tamanhos dos discos em nenhum momento durante as mudanças de especificação.

Isso ocorre porque sua reconstrução atual do contêiner falhou; e você está iniciando uma versão anterior do seu app. Esse é o comportamento normal. Quando uma reconstrução não é bem-sucedida, o contêiner original não é excluído (de modo geral) e a imagem original também permanece disponível.

Quanto ao seu problema com o PG, você precisará fornecer à equipe mais detalhes sobre a configuração do seu app e do contêiner para obter o melhor suporte.

@neounix: Obrigado.

Sou novo na hospedagem de um fórum Discourse, então não tenho certeza de onde procurar ou o que observar. Tenho uma instalação essencialmente padrão, sem plugins ou outras modificações. Defini algumas variáveis no app.yml e estou usando meu daemon Apache2 existente como proxy reverso para encaminhar o tráfego do Discourse, por meio de um virtualhost separado, para a porta localhost configurada para o Discourse ouvir.

Você poderia detalhar quais informações seriam úteis? Existe algum recurso que eu possa ler para ajudar a depurar minha situação?

O erro principal está no arquivo de log executado acima.

2020-07-01 07:19:44.162 UTC [49] FATAL:  não foi possível mapear memória compartilhada anônima: Não é possível alocar memória

2020-07-01 07:19:44.162 UTC [49] HINT:  Este erro geralmente significa que a solicitação do PostgreSQL por um segmento de memória compartilhada excedeu a memória disponível, o espaço de swap ou as páginas gigantes. Para reduzir o tamanho da solicitação (atualmente 4423172096 bytes), reduza o uso de memória compartilhada do PostgreSQL, talvez diminuindo shared_buffers ou max_connections.

Vi esse erro, mas não fiz nenhuma alteração no app.yml.Onde posso reduzir o shared_buffers ou o max_connections, já que eles não estão no app.yml? O app.yml possui apenas o parâmetro db_shared_buffers, que está definido com o valor padrão “4096MB”, como sempre foi (antes e depois de aumentar a memória do servidor).

Você pode considerar postar suas estatísticas relacionadas à memória.

Por exemplo, no Linux:

$ free -m
              total        used        free      shared  buff/cache   available
Mem:          64299       12955        9678         361       41664       50265
Swap:          7807          69        7738

e, para estatísticas do Docker, poste a saída de

docker stats

e assim por diante.

O erro está relacionado à falta de memória.

As estatísticas de memória do servidor são:

              total        usada        livre      compartilhada  buff/cache   disponível
Mem:           3951        2236         414          86        1299        1308
Swap:           511         415          96

Estatísticas de memória após enter app:

              total        usada        livre      compartilhada  buff/cache   disponível
Mem:           3951        2363         321          86        1266        1215
Swap:           511         415          96

A execução de docker stats > output.txt produziu:

        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 15.86%              6.48MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 15.86%              6.48MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.83%               6.539MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.83%               6.539MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 3.30%               6.477MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 3.30%               6.477MiB / 3.859GiB   0.16%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.45%               6.535MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25
        CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
       ca4c5f37894c        app                 2.45%               6.535MiB / 3.859GiB   0.17%               20.3kB / 12.6kB     0B / 0B             25

Olá @nap

Você pode recuperar muita memória parando e, em seguida, removendo todos aqueles antigos containers app.

Por exemplo:

docker stop <container_id>
docker rm <container_id>

Assumindo que eles não estejam em uso?

Se todos estiverem em uso, então você deve considerar aumentar a memória deste servidor para mais de 4 GB; talvez optar por 8 GB :slight_smile:

Eu parei o aplicativo com ./launcher stop app e depois executei novamente docker stats. Não havia nenhum contêiner listado.
Infelizmente, aumentar a memória significa pagar mais. O que está frustrante no momento é que estava funcionando no mês passado com 4GB.

E eu nem mesmo consigo reconstruir no momento, o que não deve consumir tanta memória.

Sem o contêiner em execução, as estatísticas de memória são:

              total        used        free      shared  buff/cache   available
Mem:           3951        2207         169          91        1574        1332
Swap:           511         446          65

Tenho alguns diretórios interessantes em ./var/lib/docker/overlay2/:

e3e6cdfcc62c2e0b68ec91efxxxxx6c69212c95b5070f7b6b84e97edcb473ea2
64a04d1b97a18f51a5fdc536xxxxxf9473de0c2ccd1a2cc0d62e830164b5f2d8
355303c6af7bebff1163195c5xxxxx8fd1de6333e39adbcb573c7365673b6c85

Posso excluí-los?

Certo.

Entendi. Eu estava ocupado trabalhando em outra tarefa e não percebi que sua saída mostrava as estatísticas do mesmo container e não de vários.

O que free -m mostra agora que seu container não está em execução?

Acho que 4 GB de RAM são suficientes para um único container, com certeza.

Não.

Não apague esses arquivos do Docker.

O problema, conforme a mensagem de erro, está relacionado à sua configuração do Discourse com o PG 12. Não tenho certeza de como resolver isso, pois acredito que ajustar o arquivo de configuração do PG 12 para o Discourse não é suportado.

Os especialistas do meta terão sugestões melhores do que as minhas, especialmente as equipes profissionais de hospedagem.

O que você está dizendo é que isso é interno aos arquivos dentro da configuração do Docker? E modificar manualmente causará problemas assim que o contêiner for iniciado ou atualizado?

@nap

Se você fizer uma busca no Google pela mensagem de erro acima (entre aspas), encontrará várias discussões diretamente relevantes sobre essa mensagem de erro exata do PostgreSQL.

Espero que isso ajude.

Depois de fazer isso, você executou novamente ./discourse-setup ou modificou manualmente as configurações de memória no app.yml? O que são db_shared_buffers, unicorn_workers e db_work_mem?

Exceto pelo fato de você estar rodando atrás de um proxy reverso, o que torna as coisas mais complicadas. Não está claro que o proxy reverso seja o culpado aqui, mas ele realmente complica as coisas.

Você tem múltiplas partições? Será que a partição onde o Docker cria imagens está cheia?

@pfaffman: Obrigado por dar uma olhada.

Não, tudo o que fiz foi adicionar uma série de definições de variáveis relacionadas ao nome do site e ao uso de tags.

db_shared_buffers é “4096MB”
unicorn_workers é 8
db_work_mem está comentado

Tenho uma partição principal de 40G (14GB livres), 512MB de swap e uma partição de 8GB para backups (não montada).

Parece que superei o problema. Inicialmente, tentei reduzir os buffers para 2GB e os workers para 4, mas obtive o mesmo erro. Em seguida, reduzi os buffers para 1GB, momento em que o rebuild foi bem-sucedido e o fórum está novamente no ar.

Obrigado a todos!!