Instalación nueva arroja 502 Bad Gateway

Hola a todos:

He configurado Discourse dos veces, una en un contenedor y la actual en una VM. En ambas instalaciones, Discourse no es accesible. No estoy muy seguro de qué podría estar mal.

VM de Discourse:

  • Núcleos 4
  • RAM 6 GB
  • Almacenamiento 50 GB
  • SO: Ubuntu 22.04.3

Comandos de instalación limpia posterior al SO:

apt update -y && apt upgrade -y && apt wget curl zip git docker.io -y && reboot

Luego seguí la siguiente guía: discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub

Una vez completado, puedo ver que el contenedor se está ejecutando, pero devuelve 502 Bad Gateway.

Cómo lo configuré: Proxy Inverso Nginx (incluye SSL) → VM. Esto no funciona.
Ni siquiera carga cuando lo agrego directamente a mi archivo hosts.

Por las últimas líneas de la instalación, puedo ver que Docker creó una nueva red:

DOCKER_HOST_IP=172.17.0.1 --name app -t -p 80:80 -p 443:443

¿Cómo hago para que use la IP de la máquina HOST?
No necesito otra red dentro de una red. Me conformo con que Docker use la IP del HOST, ya que es el único servicio en esta VM.

¡Cualquier ayuda sería muy apreciada!

¿Existe un método oficial para instalar sin Docker?

2 Me gusta

¿El contenedor está en una máquina con una IP pública? ¿Esa IP pública tiene un nombre de dominio asignado?

¿Ejecutaste discourse-setup? ¿Pasaste la parte en la que verifica si tu DNS es válido y el host está disponible?

¿Ejecutaste un montón de reconstrucciones para que te limitaran la velocidad de let’s encrypt y no puedas obtener un certificado?

No, a esta máquina se le asigna una IP local y el tráfico se enruta a la IP local a través de mi firewall. Este no es el problema.
La IP pública tiene un registro A para el servidor y se enruta correctamente. forum.somedomain.com apunta –> al servidor correcto.

Sí, he pasado la instalación. La completé al 100% (3 veces) hasta el punto en que el contenedor está en funcionamiento.
Pasa todas las verificaciones de dominio/DNS. Indica que es válido.

No, esto no puede ser limitado por tasa ya que el certificado SSL se emite a través de mi proxy inverso. Tengo el certificado.

Esta instalación está completa al 100%. El problema es que Docker está creando una nueva red 172.17.0.1 que no es necesaria, ya que me gustaría usar la IP local del HOST 192.xx.xx.xx.

El contenedor está en funcionamiento pero en una red diferente. No puedo conseguir que se conecte a la IP del HOST.

El host de docker debería ser la IP del servidor host (192.xxx.xxx.xxx) y no una red nueva. Probablemente esté funcionando pero en esa red.
¿Cómo le digo a la instalación que use mi IP local y no 172.17.0.1?

@pfaffman Algo así. De un comentario que hiciste

¿Cómo configuro ./discourse-setup para usar la IP del host 192.168.1.X y la red en la instalación?

No puedes usar discourse-setup con un proxy inverso. Tendrás que editar el archivo yml tú mismo. Hay algunos temas sobre cómo ejecutar Discourse con otros sitios en la misma máquina.

Necesitarás eliminar las plantillas ssl y lets-encrypt si estás usando un proxy inverso que se encarga de las cosas de SSL.

Ese es el problema, no estoy ejecutando ningún otro servicio en esta máquina. Es una VM independiente.

Creo que hay un malentendido.

El ./docker-setup se instala correctamente. Crea su propia red para la aplicación 172.17.0.1.

¿Cómo hago para que la instalación o el contenedor de Docker utilicen la IP del host 192.168.1.X, es decir, que usen una red bridge y no creen su propia red?

Pero dijiste esto:

Si estás usando un proxy inverso, no puedes usar discourse-setup.

Sí, el proxy inverso está en otro servidor, pero entiendo lo que dices.

Tengo una idea. Simplemente enrutaré todo el tráfico de mi red a la red de contenedores de docker.

¿Hay una guía de instalación para ejecutar discourse detrás de un proxy inverso nginx?

¿O una forma de compilar discourse yo mismo?

Eso es bastante trivial. Permites el puerto http en app.yml donde Ngix está enviando tráfico. Y SSL está deshabilitado. Esas dos cosas son las únicas que tienes que arreglar. Por supuesto, tienes que decir la IP real, pero eso siempre hay que hacerlo cuando el backend es Discourse, Moodle, WordPress o lo que sea. UFW intenta limitar el acceso solo entre el frontend y el backend porque no hay necesidad de permitir el acceso directo al backend.

Si mal no recuerdo, aquí hay documentación sobre cómo configurar Apache2. Nginx hace lo mismo, pero a su manera, por supuesto.

¿O qué me estoy perdiendo ahora?

1 me gusta

Permítame empezar desde el principio para que pueda ver que es algo simple lo que me falta.

Tengo Nginx Reverse Proxy. Ejecutando y administrando la IP pública y haciendo el enrutamiento a los servicios.

Ej: el cliente solicita cloud.domain.com → Nginx Reverse Proxy (maneja ssl) → Apunta a cloud.domain.com

Ahora he configurado una VM para discourse y he utilizado lo siguiente:
Ubuntu 23.04. Comandos posteriores a la instalación del SO:

apt update -y \
apt upgrade -y \
apt install wget curl zip git docker.io -y

Luego seguí esta guía de Discourse discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub

La instalación se completa con éxito y luego comienzan los problemas.

No puedo acceder al contenedor de Docker desde el host debido a la red docker0. Puedo hacer ping a 172.17.0.2 y está activo y funcionando, pero desde la máquina host 192.168.1.10:80/443 no pasa tráfico al contenedor.

Todo lo que quiero es que el contenedor de Docker use la red del host, ya que el contenedor tiene los puertos 80 y 443 expuestos.

El primer proxy inverso de Nginx maneja el tráfico desde el exterior y lo pasa a la VM correctamente. Si no lo hiciera, ./discourse-setup no habría captado el nombre de dominio correctamente y no podría recuperar certificados SSL para el contenedor.

Al final. Sé que el contenedor funciona al 100%, simplemente no puedo acceder a él debido a la red de Docker.

Si necesita alguna información, por favor hágamelo saber.

Otra forma de abordar esto es usar la imagen base de discourse
https://hub.docker.com/r/discourse/base
Y construir tu propia orquestación con, por ejemplo, docker compose (recordando que necesitas otros servicios como redis y postgres)

Puedo hacer eso con Nginx o Nginx+Varnish a Discourse en el mismo VPS o en un VPS con una IP diferente. No dices qué haces realmente con tu Nginx actuando como proxy inverso. Tus ejemplos son un poco difíciles porque no hay forma de saber si son ejemplos o si realmente estás intentando usar una red privada.

Pero:

Por supuesto que no, porque eso se encarga del tráfico entrante. Debes usar otro puerto para el backend.

Algo como esto (que se usa realmente con Varnish, pero el principio es totalmente el mismo, y muy básico):

proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP  $remote_addr;
proxy_set_header X-Forwarded-For
 $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header Host $host;
proxy_pass_header Server;

Entendible, gracias por ser específico :).

No estoy seguro de qué, porque esta red de Docker es confusa.

Absolutamente, por eso me frustro con Docker, lol.

Abajo está exactamente cómo la red WAN pasa y enruta el tráfico de mi proxy inverso nginx al host correcto.

map $scheme $hsts_header {
    https   "max-age=63072000;includeSubDomains; preload";
}

server {
  set $forward_scheme https;
  set $server         "10.10.1.38";
  set $port           443;

  listen 80;
listen [::]:80;

  listen 443 ssl http2;
listen [::]:443 ssl http2;


  server_name forum.domainname.com;

  # Let's Encrypt SSL
  include conf.d/include/letsencrypt-acme-challenge.conf;
  include conf.d/include/ssl-ciphers.conf;
  ssl_certificate /srv/ssl/domainname.pem;
  ssl_certificate_key /srv/ssl/domainname-ke.pem;


# Asset Caching
include conf.d/include/assets.conf;

# Block Exploits
include conf.d/include/block-exploits.conf;

# HSTS (se requiere ngx_http_headers_module) (63072000 segundos = 2 años)
add_header Strict-Transport-Security $hsts_header always;

# Force SSL
include conf.d/include/force-ssl.conf;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;


access_log /var/logs/domainname-access.log proxy;
error_log /var/logs/domainame_error.log warn;

proxy_set_header  X-Real-IP $remote_addr;
proxy_set_header  X-Forwarded-For $http_x_forwarded_for;
proxy_set_header  X-Forwarded-Proto $scheme;

location / {

  # HSTS (se requiere ngx_http_headers_module) (63072000 segundos = 2 años)
  add_header Strict-Transport-Security $hsts_header always;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;
    
    # Proxy!
    include conf.d/include/proxy.conf;
  }
}

Lo raro es que configuré un contenedor docker una vez para un cliente que quería nginx reverse proxy manager y fue extremadamente simple.

docker-compose up -d
Eso fue todo. La IP privada 192.168.1.3 podía alcanzar los 80/443 expuestos de los contenedores y el tráfico saliente se enrutaba correctamente a 192.168.1.3.

Es confusa porque es un sistema de empaquetado que funciona en su propia caja de arena. Básicamente, eso es.

Pero entender Docker es una cosa diferente a usarlo (y ahora un montón de desarrolladores empezaron a llorar :rofl:). Tu proxy inverso está enviando tráfico a la IP a través del firewall y tienes que decirle esa IP y el puerto de escucha. Y tienes Discourse, también conocido como Docker, en esa IP, y el puerto que dices en app.yml. El Nginx interno que trabaja con Discourse se encarga del resto.

Discourse no debería escuchar en el puerto 443 porque ya terminaste SSL.

Y básicamente no puedes usar caché en el proxy inverso. El backend, Discourse, no es una página web. Es una aplicación web que envía JavaScript y JSON.

Algo así lo he entendido.

En eso sí que estoy de acuerdo. No diría llorar, simplemente es inútil para los administradores de sistemas y desarrolladores que realmente saben moverse en Linux. Crear un LxC o una VM que esté aislada para luego dejar que docker cree otro entorno aislado es redundante y sin sentido.

Esta es la parte que confunde. app.yml está exponiendo 80:80 y 443:443 en 172.17.0.2, que está en la red docker 172.17.0.1/16 con la IP de la VM en 10.10.1.38.

¿Cómo consigo que discourse/docker permita que todo el tráfico que llega a 10.10.1.38 se pase a 172.17.0.2 y que todo el tráfico saliente se pase a 10.10.1.38? Eso es todo lo que se necesita para resolver este problema. Literalmente.

Mi proxy inverso se encargará del enrutamiento desde la WAN a forum.domainname.com

La caché ha sido eliminada.

1 me gusta

Solo si no los cambias. Como deberías y usas un solo puerto.

80:80 y 443:443 son valores predeterminados y se usan por sí mismos solo cuando no hay un proxy inverso, o nada más, actuando como frontend.

1 me gusta

Me diste una idea.

Estuve ocupado revisando todos los archivos base y creo que lo he descubierto.

Tan simple, jajaja. Estoy ocupado reconstruyendo, esto podría funcionar al 100% utilizando los métodos de instalación estándar admitidos oficialmente.

Éxito El foro se ha instalado y está funcionando.

Usando el método de instalación estándar y compatible :smiley:


2 Me gusta

@pfaffman Puedes mover esto a instalación, ya que ahora es una instalación compatible.

Ahí está. Simplemente está etiquetado como no compatible :smirking_face:

¿Cuál fue tu problema en primer lugar por qué no empezaste a instalar sin proxy inverso? Solo tengo curiosidad.