Discourse Bad Gateway tras reinicio

Mi servidor se ejecuta en una máquina virtual alojada por uno de los principales proveedores de servicios en la nube.
Instalé correctamente discourse en ella y ha estado funcionando sin problemas durante el último mes.
Hoy, decidí cambiar las especificaciones de mi VM a su configuración original (*) y reiniciar. Al iniciar, aunque todo lo demás en mi servidor funciona correctamente, obtengo un error 502 Bad Gateway al intentar acceder al foro de Discourse. Pensando que la instancia de Docker no se había iniciado automáticamente, me conecté por SSH a mi servidor y ejecuté ./launcher start app, pero recibí un mensaje indicando que había espacio insuficiente restante (5 GB disponibles), así que ejecuté df -h, lo cual me indica que en realidad tengo 14 GB disponibles. Entonces, ejecuté ./launcher start app de nuevo, pero esta vez obtuve una advertencia de que Docker iba a descargar cosas y que fuera paciente. Después de cierto procesamiento, recibí el mensaje Nothing to do, your container has already started!. Sin embargo, mis intentos de acceder al foro siguen devolviendo 502 Bad Gateway.
Después de consultar este foro, decidí ejecutar ./launcher rebuild app y obtuve los siguientes errores, relacionados con PostgreSQL:

    user@host:[16:48]:/var/discourse# ./launcher rebuild app
    Asegurando que el lanzador esté actualizado
    Obteniendo origen
    El lanzador está actualizado
    Deteniendo el contenedor anterior
    + /usr/bin/docker stop -t 60 app
    app
    cd /pups && git pull && /pups/bin/pups --stdin
    Ya está actualizado.
    I, [2020-07-01T07:19:42.821347 #1]  INFO -- : Cargando --stdin
    I, [2020-07-01T07:19:42.831806 #1]  INFO -- : > locale-gen $LANG && update-locale
    I, [2020-07-01T07:19:42.879007 #1]  INFO -- : Generando configuraciones regionales (esto podría tomar un tiempo)...
    Generación completada.
    
    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 ya se está ejecutando, detener contenedor ; exit 1
    2020/07/01 07:19:42 socat[26] E connect(6, AF=1 "/shared/postgres_run/.s.PGSQL.5432", 36): No existe tal archivo o directorio
    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 -- : Archivo > /etc/service/postgres/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.973345 #1]  INFO -- : Archivo > /etc/service/postgres/log/run  chmod: +x  chown:
    I, [2020-07-01T07:19:42.983929 #1]  INFO -- : Archivo > /etc/runit/3.d/99-postgres  chmod: +x  chown:
    I, [2020-07-01T07:19:42.994843 #1]  INFO -- : Archivo > /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 -- : Reemplazando data_directory = '/var/lib/postgresql/12/main' por data_directory = '/shared/postgres_data' en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.093969 #1]  INFO -- : Reemplazando (?-mix:#?listen_addresses *=.*) por listen_addresses = '*' en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095204 #1]  INFO -- : Reemplazando (?-mix:#?synchronous_commit *=.*) por synchronous_commit = $db_synchronous_commit en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.095937 #1]  INFO -- : Reemplazando (?-mix:#?shared_buffers *=.*) por shared_buffers = $db_shared_buffers en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.096695 #1]  INFO -- : Reemplazando (?-mix:#?work_mem *=.*) por work_mem = $db_work_mem en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.097554 #1]  INFO -- : Reemplazando (?-mix:#?default_text_search_config *=.*) por default_text_search_config = '$db_default_text_search_config' en /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 -- : Reemplazando (?-mix:#?max_wal_senders *=.*) por max_wal_senders = $db_max_wal_senders en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.114973 #1]  INFO -- : Reemplazando (?-mix:#?wal_level *=.*) por wal_level = $db_wal_level en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.116047 #1]  INFO -- : Reemplazando (?-mix:#?checkpoint_segments *=.*) por checkpoint_segments = $db_checkpoint_segments en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.117033 #1]  INFO -- : Reemplazando (?-mix:#?logging_collector *=.*) por logging_collector = $db_logging_collector en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.118051 #1]  INFO -- : Reemplazando (?-mix:#?log_min_duration_statement *=.*) por log_min_duration_statement = $db_log_min_duration_statement en /etc/postgresql/12/main/postgresql.conf
    I, [2020-07-01T07:19:44.119352 #1]  INFO -- : Reemplazando (?-mix:^#local +replication +postgres +peer$) por local replication postgres peer en /etc/postgresql/12/main/pg_hba.conf
    I, [2020-07-01T07:19:44.120299 #1]  INFO -- : Reemplazando (?-mix:^host.*all.*all.*127.*$) por host all all 0.0.0.0/0 md5 en /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) en 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:  escuchando en dirección IPv4 "0.0.0.0", puerto 5432
    2020-07-01 07:19:44.158 UTC [49] LOG:  escuchando en dirección IPv6 "::", puerto 5432
    2020-07-01 07:19:44.161 UTC [49] LOG:  escuchando en socket Unix "/var/run/postgresql/.s.PGSQL.5432"
    2020-07-01 07:19:44.162 UTC [49] FATAL:  no se pudo mapear memoria compartida anónima: No se puede asignar memoria
    2020-07-01 07:19:44.162 UTC [49] HINT:  Este error generalmente significa que la solicitud de un segmento de memoria compartida de PostgreSQL excedió la memoria disponible, el espacio de intercambio o las páginas grandes. Para reducir el tamaño de la solicitud (actualmente 4423172096 bytes), reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo shared_buffers o max_connections.
    2020-07-01 07:19:44.162 UTC [49] LOG:  el sistema de base de datos se ha apagado
    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: error: no se pudo conectar a la base de datos template1: no se pudo conectar al servidor: No existe tal archivo o directorio
        ¿Está el servidor ejecutándose localmente y aceptando
        conexiones en el socket de dominio 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: error: no se pudo conectar al servidor: no se pudo conectar al servidor: No existe tal archivo o directorio
        ¿Está el servidor ejecutándose localmente y aceptando
        conexiones en el socket de dominio 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: error: no se pudo conectar al servidor: no se pudo conectar al servidor: No existe tal archivo o directorio
        ¿Está el servidor ejecutándose localmente y aceptando
        conexiones en el socket de dominio 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: error: no se pudo conectar al servidor: no se pudo conectar al servidor: No existe tal archivo o directorio
        ¿Está el servidor ejecutándose localmente y aceptando
        conexiones en el socket de dominio 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 -- : Terminando procesos asíncronos
    
    
    FALLO
    --------------------
    Pups::ExecError: su postgres -c 'psql discourse -c "alter schema public owner to discourse;"' falló con retorno #<Process::Status: pid 75 exit 2>
    Ubicación del fallo: /pups/lib/pups/exec_command.rb:112:in `spawn'
    exec falló con los parámetros "su postgres -c 'psql $db_name -c \"alter schema public owner to $db_user;\"'"
    eb41679f76cd749ccd8c84a7543365d093619b80df6fc6750b9349fb63565fa1
    ** FALLO AL INICIAR ** por favor, desplácese hacia arriba y busque mensajes de error anteriores, puede haber más de uno.
    ./discourse-doctor puede ayudar a diagnosticar el problema.
    user@host:[17:19]:/var/discourse#

Curiosamente, a pesar de los errores anteriores, ejecutar ./launcher start app no produce errores:

iniciando contenedor existente
+ /usr/bin/docker start app
app

Con la instancia en ejecución, intenté usar ./launcher enter app para entrar en el contenedor. (En mi humilde opinión, las herramientas disponibles en el contenedor son muy pobres (sí, soy usuario de nano y me gusta tener varios alias mapeados; por ejemplo, ll). No puedo encontrar la ruta física a las carpetas dentro de la instancia de Docker (ya que me gustaría descargarlas usando un cliente FTP).

En /var/log/nginx/error.log tengo la siguiente entrada de error cada vez que actualizo mi navegador:

2020/07/01 07:44:16 [error] 646#646: *3 connect() falló (111: Conexión rechazada) al conectar con el upstream, cliente: xxx.xx.0.1, servidor: _, solicitud: "GET / HTTP/1.1", upstream: "http://127.0.0.1:3000/", host: "discourse.miDominio.com"

¿Qué podría ser la causa de mi problema? ¿Por qué PostgreSQL de repente no funciona?

(*) Una semana después de instalar Discourse, actualicé mi servidor con más CPUs y memoria. Necesitaba hacer esto para ejecutar una conferencia de video que organicé. Una vez terminada la conferencia, volví a mi configuración normal. Tenga en cuenta que no cambié los tamaños de disco en ningún momento durante los cambios de especificaciones.

Esto se debe a que tu reconstrucción actual del contenedor falló y estás iniciando una versión anterior de tu app. Este es el comportamiento normal. Cuando una reconstrucción no tiene éxito, el contenedor original no se elimina (en términos generales) y la imagen original también sigue disponible.

En cuanto a tu problema con PG, necesitarás proporcionar al equipo más detalles sobre tu aplicación y la configuración del contenedor para obtener el mejor soporte.

@neounix: Gracias.

Soy nuevo en la administración de un foro de Discourse, así que no estoy seguro de dónde buscar ni en qué fijarme. Tengo una instalación esencialmente estándar, sin plugins ni otras modificaciones. He definido algunas variables en app.yml y estoy utilizando mi servicio Apache2 existente como proxy inverso para redirigir el tráfico de Discourse, a través de un host virtual separado, al puerto de localhost en el que he configurado Discourse para escuchar.

¿Podrías ampliar qué información sería útil? ¿Existe algún recurso que pueda leer para ayudarme a depurar mi situación?

El error principal se encuentra en el archivo de registro mostrado arriba.

2020-07-01 07:19:44.162 UTC [49] FATAL:  no se pudo mapear memoria compartida anónima: No se puede asignar memoria

2020-07-01 07:19:44.162 UTC [49] HINT:  Este error generalmente significa que la solicitud de PostgreSQL para un segmento de memoria compartida superó la memoria disponible, el espacio de intercambio o las páginas grandes. Para reducir el tamaño de la solicitud (actualmente 4423172096 bytes), reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo shared_buffers o max_connections.

Vi ese error, pero no he realizado ningún cambio en app.yml.
¿Dónde puedo reducir shared_buffers o max_connections, si no están en app.yml? app.yml solo tiene un parámetro db_shared_buffers, pero está configurado con el valor predeterminado “4096MB”, como siempre ha estado (antes y después de aumentar la memoria del servidor).

Podrías considerar publicar tus estadísticas relacionadas con la memoria.

Por ejemplo, en Linux:

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

y para las estadísticas de Docker, publica la salida de

docker stats

etc.

El error está relacionado con la falta de memoria.

Las estadísticas de memoria del servidor son:

              total        usada        libre      compartida  buff/cache   disponible
Mem:           3951        2236         414          86        1299        1308
Swap:           511         415          96

Estadísticas de memoria después de enter app:

              total        usada        libre      compartida  buff/cache   disponible
Mem:           3951        2363         321          86        1266        1215
Swap:           511         415          96

Ejecutar docker stats > output.txt produjo:

        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

Hola @nap

Puedes recuperar mucha memoria deteniendo y luego eliminando todos esos contenedores antiguos de app.

Por ejemplo:

docker stop <container_id>
docker rm <container_id>

¿Asumiendo que no están en uso?

Si todos están en uso, entonces deberías considerar aumentar la memoria de este servidor por encima de 4 GB; quizás optar por 8 GB :slight_smile:

Detuve la aplicación con ./launcher stop app y luego volví a ejecutar docker stats. No se listaron contenedores.

Lamentablemente, aumentar la memoria implica pagar más. Lo más frustrante en este momento es que el mes pasado funcionaba con 4 GB.

Y ni siquiera puedo reconstruir en este momento, lo cual no debería consumir tanta memoria.

Sin el contenedor en ejecución, las estadísticas de memoria son:

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

Tengo algunos directorios interesantes en ./var/lib/docker/overlay2/:

e3e6cdfcc62c2e0b68ec91efxxxxx6c69212c95b5070f7b6b84e97edcb473ea2
64a04d1b97a18f51a5fdc536xxxxxf9473de0c2ccd1a2cc0d62e830164b5f2d8
355303c6af7bebff1163195c5xxxxx8fd1de6333e39adbcb573c7365673b6c85

¿Puedo eliminarlos?

Correcto.

Entiendo. Estaba ocupado trabajando en otra tarea y no noté que tu salida mostraba las estadísticas del mismo contenedor y no de varios.

¿Qué te dice ahora free -m con tu contenedor detenido?

Creo que los 4 GB de RAM están bien para un solo contenedor, sin duda.

No.

No elimines esos archivos de Docker.

El problema, según el mensaje de error, está relacionado con tu configuración de Discourse PG 12. No estoy seguro de cómo abordarlo, ya que creo que no se admite ajustar el archivo de configuración de PG 12 para Discourse.

Los expertos de meta tendrán mejores sugerencias que yo, especialmente los equipos de alojamiento profesional.

¿Lo que estás diciendo es que esto es interno a los archivos dentro de la configuración de Docker? ¿Y que modificarlo manualmente causará problemas una vez que el contenedor se inicie o se actualice?

@nap

Si buscas en Google el mensaje de error anterior (entre comillas), encontrarás varias discusiones directamente relevantes sobre este mensaje de error exacto de PostgreSQL.

Espero que esto ayude.

¿Después de hacer eso, volviste a ejecutar ./discourse-setup o modificaste a mano la configuración de memoria en app.yml? ¿Qué son db_shared_buffers, unicorn_workers y db_work_mem?

Excepto que estás ejecutando detrás de un proxy inverso, lo que complica las cosas. No está claro que el proxy inverso sea el culpable aquí, pero sí complica las cosas.

¿Tienes múltiples particiones? ¿Podría ser que la partición donde Docker crea las imágenes esté llena?

@pfaffman: Gracias por echar un vistazo.

No, lo único que hice fue agregar una serie de definiciones de variables relacionadas con el nombre del sitio y el uso de etiquetas.

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

Tengo una partición principal de 40G (14GB libres), 512MB de swap y una partición de 8GB para copias de seguridad (no montada).

Parece que he superado el problema. Inicialmente intenté reducir los buffers a 2GB y los workers a 4, pero obtuve el mismo error. Luego reduje los buffers a 1GB, momento en el cual rebuild tuvo éxito y el foro ya está de nuevo en línea.

¡Gracias a todos!