⚠ El puerto 443 de este equipo no parece ser accesible usando el nombre de host: metabolism.logophilia.eu ----

Hola, obtengo el error mencionado en el asunto (véase también más abajo) después de recibir el mensaje “ Los puertos 80 y 443 están libres para su uso” durante la inicialización. El DNS está configurado, SSL está configurado y el sitio web funciona desde el exterior (pruébalo tú mismo). La salida de curl (recortada) se incluye a continuación, es decir, es accesible desde la propia máquina. Se me han acabado las ideas sobre qué falta. Gracias por cualquier aclaración.

PS. AlmaLinux 10.2 - 6.12.0-211.7.4.el10_2.x86_64

# ./discourse-setup  
→ Comprobando actualizaciones de la imagen del asistente de configuración... 
→ Iniciando el Asistente de Configuración de Discourse... 
 
 
 ___  _ 
|   \(_)___ __ ___ _  _ _ _ ___ ___ 
| |) | (_-\<\/ _/ _ \\ || | '_(_-\<\/ -_) 
|___/|_/__/\\__\\___/\\_,_|_| /__/\\___| 
                       Asistente de Configuración 
 
 
→ Este asistente te ayudará a configurar tu instalación de Discourse. 
→ Pulsa Ctrl+C en cualquier momento para cancelar. 
 
── Comprobaciones del sistema ── 
 
[1/5] Verificando los requisitos del sistema 
✓ Ejecutándose como root 
✓ Docker está disponible 
✓ Memoria: 8 GB, CPU: 4 núcleos 
 
── Configuración ── 
 
[2/5] Preparando la configuración 
✓ Los puertos 80 y 443 están libres para su uso 
→ Creando nueva configuración... 
→ Creando nueva configuración a partir de la plantilla... 
 
── Configuración del sitio ── 
 
[3/5] Introduce los detalles de tu sitio 
 
¿Dirección de correo electrónico para la(s) cuenta(s) de administrador? 
eduard.pech@logophilia.eu▌ 
 
¿Tienes un nombre de dominio para tu Discourse? 
▸ Sí      No 
 
¿Nombre de host para tu Discourse? 
metabolism.logophilia.eu▌ 
 
¿Configurar SMTP para enviar correos electrónicos? (Requiere credenciales de SMTP) 
  Sí    ▸ No 
 
 
── Revisión de la configuración ── 
 
 
╭────────────────────────────────────────────╮ 
│                                            │ 
│  Nombre de host       metabolism.logophilia.eu   │ 
│  Correo del admin    eduard.pech@logophilia.eu  │ 
│  SMTP           (no configurado)           │ 
│  Let's Encrypt  Habilitado                    │ 
│                                            │ 
╰────────────────────────────────────────────╯ 
 
 
¿Se ve bien esto? 
▸ Sí      No 
→ Se encontraron 8 GB de memoria y 4 núcleos de CPU 
→ Estableciendo db_shared_buffers = 2048MB 
→ Estableciendo UNICORN_WORKERS = 8 
 
── Validación de red ── 
 
[4/5] Verificando la configuración del dominio 
→ Comprobando tu nombre de dominio... 
⚠ El puerto 443 de este equipo no parece ser accesible mediante el nombre de host: metabolism.logophilia.eu 
⚠ La conexión a http://metabolism.logophilia.eu (puerto 80) también falla. 
 
Esto sugiere que metabolism.logophilia.eu se resuelve a una dirección IP que no alcanza la máquina 
en la que estás instalando Discourse. 
 
Lo primero que debes hacer es confirmar que metabolism.logophilia.eu se resuelve a la dirección IP de este servidor. 
Por lo general, esto se hace en el mismo lugar donde compraste el dominio. 
 
Si estás seguro de que la dirección IP se resuelve correctamente, podría tratarse de un problema con el firewall. 
Una búsqueda web sobre "abrir puertos TU SERVICIO EN LA NUBE" podría ayudarte. 
 
Esta herramienta está diseñada solo para las instalaciones más estándar. Si no puedes resolver 
el problema anterior, tendrás que editar containers/app.yml tú mismo y luego escribir: 
 
    ./launcher rebuild app 
 
 
✗ La verificación de DNS falló para metabolism.logophilia.eu 
[root@logophilia discourse]# dig metabolism.logophilia.eu 
 
; <<>> DiG 9.18.33 <<>> metabolism.logophilia.eu 
;; opciones globales: +cmd 
;; Respuesta recibida: 
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 36726 
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 
 
;; SECCIÓN PSEUDO OPT: 
; EDNS: versión: 0, flags:; udp: 512 
;; SECCIÓN DE PREGUNTA: 
;metabolism.logophilia.eu.      IN      A 
 
;; SECCIÓN DE RESPUESTA: 
metabolism.logophilia.eu. 300   IN      A       75.119.134.68 
 
;; Tiempo de consulta: 8 msec 
;; SERVIDOR: 213.136.95.10#53(213.136.95.10) (UDP) 
;; CUANDO: Sáb Jun 06 04:52:23 CEST 2026 
;; TAMAÑO DEL MENSAJE rcvd: 69 
 
[root@logophilia discourse]# curl -v https://metabolism.logophilia.eu 
* Host metabolism.logophilia.eu:443 resuelto. 
* IPv6: (ninguno) 
* IPv4: 75.119.134.68 
*   Intentando conectar a 75.119.134.68:443... 
* ALPN: curl ofrece h2,http/1.1 
* TLSv1.3 (SALIDA), saludo TLS, Cliente hello (1): 
*  CAfile: /etc/pki/tls/certs/ca-bundle.crt 
*  CApath: ninguno 
* TLSv1.3 (ENTRADA), saludo TLS, Servidor hello (2): 
* TLSv1.3 (ENTRADA), cambio de cifrado TLS, Especificación de cambio de cifrado (1): 
* TLSv1.3 (ENTRADA), saludo TLS, Extensiones cifradas (8): 
* TLSv1.3 (ENTRADA), saludo TLS, Certificado (11): 
* TLSv1.3 (ENTRADA), saludo TLS, Verificación de CERT (15): 
* TLSv1.3 (ENTRADA), saludo TLS, Finalizado (20): 
* TLSv1.3 (SALIDA), cambio de cifrado TLS, Especificación de cambio de cifrado (1): 
* TLSv1.3 (SALIDA), saludo TLS, Finalizado (20): 
* Conexión SSL usando TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS 
* ALPN: el servidor aceptó http/1.1 
* Certificado del servidor: 
*  sujeto: CN=metabolism.logophilia.eu 
*  fecha de inicio: 06 de jun. de 2026 00:26:43 GMT 
*  fecha de caducidad: 04 de sep. de 2026 00:26:42 GMT 
*  subjectAltName: el host "metabolism.logophilia.eu" coincide con el certificado "metabolism.logophilia.eu" 
*  emisor: C=US; O=Let's Encrypt; CN=YR2 
*  Verificación del certificado SSL correcta. 
*   Nivel del certificado 0: Tipo de clave pública RSA (2048/112 Bits/secBits), firmado con sha256WithRSAEncryption 
*   Nivel del certificado 1: Tipo de clave pública RSA (2048/112 Bits/secBits), firmado con sha256WithRSAEncryption 
*   Nivel del certificado 2: Tipo de clave pública RSA (4096/152 Bits/secBits), firmado con sha256WithRSAEncryption 
*   Nivel del certificado 3: Tipo de clave pública RSA (4096/152 Bits/secBits), firmado con sha256WithRSAEncryption 
* Conectado a metabolism.logophilia.eu (75.119.134.68) puerto 443 
* usando HTTP/1.x 
> GET / HTTP/1.1 
> Host: metabolism.logophilia.eu 
> User-Agent: curl/8.12.1 
> Accept: */* 
>  
* Solicitud completamente enviada 
* TLSv1.3 (ENTRADA), saludo TLS, Boletín de nueva sesión (4): 
* TLSv1.3 (ENTRADA), saludo TLS, Boletín de nueva sesión (4): 
< HTTP/1.1 200 OK 
< Fecha: Sáb, 06 Jun 2026 02:52:36 GMT 
< Servidor: Apache 
< Última-modificación: Sáb, 06 Jun 2026 01:25:19 GMT 
< ETag: "1325f-6538ba67ff892" 
< Rangos aceptados: bytes 
< Longitud del contenido: 78431 
< Tipo de contenido: text/html; charset=UTF-8 
<  
<!doctype html> 
<html lang="en" data-bs-theme="auto"> 
<head> 
  <title> 
    metabolism.logophilia.eu &mdash;  Página de bienvenida del dominio para  </title> 
  <meta charset="utf-8">
……


Hola,

He revisado tu sitio web personalmente. Parece que tu proveedor de alojamiento está ocupando el puerto 443 para mostrar esta página de bienvenida. Necesitarás averiguar cómo liberar completamente los puertos 443/80 para que Discourse pueda controlarlos.

Ya hice eso; el VPS se gestiona con Virtualmin y solo es una casilla de verificación. Lamentablemente, cuando desmarco “sitio web habilitado”, no puedo hacer curl al puerto 443/80 desde el host, y la configuración de Discourse sigue quejándose con el mismo error. Así que pensé en volver a habilitar el sitio web, para que al menos pueda demostrar que el handshake SSL funciona.
Y como puedes ver en mi publicación original, la configuración de Discourse afirma (inicialmente) que el puerto 443 está disponible. Es mi primera instalación, y lo interpretaría como: todo en verde. Entonces, ¿por qué la configuración “cambia de opinión”?
Por otro lado, no necesito entender cada detalle. Solo digo: con Apache deshabilitado en el subdominio, el resultado de la configuración de Discourse es el mismo.

Gracias por tomarte el tiempo. Si hay algo más que pueda aportar para aclarar las cosas, haré (casi) lo que sea.

Yo tuve el mismo problema aquí (en mi propio servidor en casa):

Creo que la solución es simplemente hacer esto si estás 100% seguro de que el DNS es correcto y tus puertos funcionan adecuadamente.

./install-discourse --skip-connection-test

¡Gracias, parece que ha funcionado! :purple_heart:

El script ahora está más allá de 5/5 y parece que está subiendo e instalando muchas cosas adicionales. El certificado SSL ahora es incorrecto; supongo que está esperando a que se agote el tiempo de vida (TTL) o quizás estará bien cuando termine la configuración.

Aunque no tengo ni idea de Discourse, ni de Docker, ni siquiera de Ruby… el tema del DNS nunca es un problema :slight_smile: ¡Gracias de nuevo!

Veo que ya está marcado como solución. Pero tengo una pregunta más, si me lo permiten.

Sé que se necesita PostgreSQL, pero no se menciona en

https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md

Así que pensé que la imagen de Docker venía con PostgreSQL instalado. ¿Podría aclarar si necesito instalar PostgreSQL en el VPS? Porque las instrucciones de instalación no lo mencionan.

… o quizás Docker incluye PostgreSQL, pero el script falló de alguna manera? Porque se detiene al final:

........
I, [2026-06-06T04:23:49.114769 #1]  INFO -- : Archivo > /etc/runit/1.d/install-ssl  chmod: +x  chown: 
I, [2026-06-06T04:23:49.114999 #1]  INFO -- : Reemplazando # después de ssl con if [ -z "$DISABLE_LETSENCRYPT" ] || [ -n "$ENABLE_LETSENCRYPT" ]; then
  /usr/local/bin/configure-ssl
  exec /usr/local/bin/configure-letsencrypt
fi
# después de ssl en /etc/runit/1.d/install-ssl
I, [2026-06-06T04:23:49.125964 #1]  INFO -- : Archivo > /usr/local/bin/configure-ssl  chmod: +x  chown: 
I, [2026-06-06T04:23:49.127031 #1]  INFO -- : > curl https://raw.githubusercontent.com/acmesh-official/acme.sh/3.0.6/acme.sh > /opt/acme.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  215k  100  215k    0     0   635k      0 --:--:-- --:--:-- --:--:--  637k
I, [2026-06-06T04:23:49.514883 #1]  INFO -- : > chmod +x /opt/acme.sh
I, [2026-06-06T04:23:49.554670 #1]  INFO -- : Archivo > /usr/local/bin/configure-letsencrypt  chmod: +x  chown: 
I, [2026-06-06T04:23:49.596808 #1]  INFO -- : Archivo > /usr/local/bin/letsencrypt  chmod: +x  chown: 
I, [2026-06-06T04:23:49.598926 #1]  INFO -- : > echo "Inicio de comandos personalizados"
Inicio de comandos personalizados
I, [2026-06-06T04:23:49.605809 #1]  INFO -- : > echo "Fin de comandos personalizados"
Fin de comandos personalizados
I, [2026-06-06T04:23:49.608842 #1]  INFO -- : Finalizando procesos asíncronos
I, [2026-06-06T04:23:49.609015 #1]  INFO -- : Enviando INT a HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/15/bin/postmaster -D /etc/postgresql/15/main pid: 44
I, [2026-06-06T04:23:49.609157 #1]  INFO -- : Enviando TERM a exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 111
2026-06-06 04:23:49.609 UTC [44] LOG:  recibido solicitud de apagado rápido
111:signal-handler (1780719829) Recibido SIGTERM programando apagado...
2026-06-06 04:23:49.612 UTC [44] LOG:  abortando cualquier transacción activa
2026-06-06 04:23:49.619 UTC [44] LOG:  trabajador en segundo plano "lanzador de replicación lógica" (PID 58) salió con código de salida 1
2026-06-06 04:23:49.623 UTC [53] LOG:  apagando
2026-06-06 04:23:49.634 UTC [53] LOG:  punto de control iniciado: apagado inmediato
111:M 06 Jun 2026 04:23:49.683 * El usuario solicitó el apagado...
111:M 06 Jun 2026 04:23:49.683 * Guardando la instantánea RDB final antes de salir.
111:M 06 Jun 2026 04:23:49.698 * Base de datos guardada en disco
111:M 06 Jun 2026 04:23:49.700 # Redis está listo para salir, adiós...
2026-06-06 04:23:49.711 UTC [53] LOG:  punto de control completado: escribió 87 búferes (0.0%); 0 archivo(s) WAL agregados, 0 eliminados, 0 reciclados; write=0.041 s, sync=0.022 s, total=0.088 s; sync files=52, longest=0.008 s, average=0.001 s; distance=86 kB, estimate=86 kB
2026-06-06 04:23:49.735 UTC [44] LOG:  el sistema de base de datos se ha apagado

No instales Postgres.

Eso es esperado, porque no has instalado Discourse como servidor web.

Entonces (casi con certeza) aún tienes el problema de que los puertos de tu máquina virtual no están expuestos a Internet.

No lo hace. Dice claramente que Discourse no tiene acceso al puerto. Además, tu comando curl muestra que algo más tiene el control del puerto 443.

Creo que el contenedor se construyó correctamente, pero no puede iniciarse porque algo más tiene el puerto 443, o no está haciendo nada porque el puerto 443 está enroutado a otro lugar.

Puedes probar

docker ps

para ver si hay contenedores en ejecución y

docker logs app

para ver qué ha registrado Discourse a través de Docker.

Gracias por la retroalimentación, realmente aprecio el tiempo dedicado. No quiero ser ese sabihondo, pero:

[2/5] Preparando configuración 
✓ Los puertos 80 y 443 están libres para su uso 

En realidad, al principio dice “libres para su uso”. Dicho esto, ahora tengo mi instancia en funcionamiento, con la ayuda de Gemini (principalmente sobre el uso de Docker, por todas esas cosas, lol). Me gustaría ofrecer mi “manual de procedimientos” para cualquier otro usuario de Virtualmin, porque: “liberar el puerto 443” no es la solución aquí. El resto de mi publicación será eso; si debería publicarlo en otro lugar, como un nuevo hilo, por favor díganme a dónde ir; creo que no soy el único con esta configuración y podría ser útil para otros. ¡Gracias de nuevo!

Si estás en un VPS gestionado por Webmin/Virtualmin y usando un subdominio:

El manual definitivo de Virtualmin + Discourse *

  • (1) Limpieza de restos (si estás reintentando, como yo):

    rm -rf /var/discourse/shared/standalone/ssl/*

    rm -rf /var/discourse/shared/standalone/letsencrypt

    rm -rf /var/discourse/shared/standalone/state

  • (2) Eliminación de plantillas:

    Debes eliminar completamente las líneas templates/web.ssl.template.yml y templates/web.letsencrypt.ssl.template.yml de app.yml. El analizador personalizado del lanzador las evaluará incluso si están precedidas por #.

  • (3) Configuración de correo y variables:

    Cambia DISCOURSE_SKIP_EMAIL_SETUP de '1' a '0', porque tu Discourse no podrá conectarse y verificar DiscordID;

    Agrega DISCOURSE_FORCE_HTTPS: true para que el backend genere URLs seguras.

    Recordatorio amigable: Asegúrate de que DISCOURSE_SMTP_USER_NAME esté configurado con el nombre de tu cuenta de buzón tal cual (por ejemplo, 'logophilia'), no la dirección de correo completa (por ejemplo, 'logophilia@logophilia.eu'), y envuelve las credenciales entre comillas simples (') para evitar posibles errores de análisis de caracteres YAML.

  • (4) Configuración del bloque expose:

    Asegúrate de que tu bloque expose: en app.yml contenga una asignación HTTP; asignar 443=>8443 es opcional/redundante, ya que Virtualmin finaliza la lógica SSL antes de pasarla:

    expose:
      - 8080:80
    

    Ahora puedes comenzar a reconstruir:

    cd /var/discourse
    ./launcher rebuild app
    
  • (5) Configuración de subdominio y ruta de proxy:

    • Crea tu subdominio en Virtualmin como de costumbre y asegúralo con un certificado SSL de Let’s Encrypt (se hace automáticamente, solo digo: asegúrate de que no falle por alguna razón no relacionada).
    • Navega a Rutas de proxy (Virtualmin → tu subdominio → Configuración web → Rutas de proxy), crea una nueva asignación / a http://localhost:8080/, deja “servir localmente” desmarcado, pero activa Proxy WebSocket a para permitir actualizaciones en tiempo real y flujos de notificaciones.
  • (6) Directivas de encabezado CSRF:

    • En Webmin ➔ Servidores ➔ Servidor web Apache ➔ [encuentra tu configuración de subdominio aquí y haz clic en la configuración para 443] ➔ Editar directivas, coloca las siguientes líneas justo encima del bloque de proxy propio de Virtualmin para Let’s Encrypt (usualmente “ProxyPass /.well-known !”) para facilitar el reenvío del token CSRF:
    ProxyPreserveHost On
    RequestHeader set X-Forwarded-Proto "https"
    RequestHeader set X-Forwarded-For %{REMOTE_ADDR}s
    

    ProxyPreserveHost On: Le dice a Discourse tu nombre de dominio real en lugar de “localhost”.
    RequestHeader set X-Forwarded-Proto "https": Le indica explícitamente a Discourse que el usuario está usando una conexión segura, coincidiendo con tu configuración DISCOURSE_FORCE_HTTPS: true.
    RequestHeader set X-Forwarded-For: Pasa la dirección IP real del visitante al contenedor para que funcionen los registros de seguridad.

  • (7) Handshake limpio del contenedor:

    Mientras termina el proceso de reconstrucción (lo siento… pero es cierto;-), asegúrate de borrar cualquier plano de contenedor potencialmente atascado con docker rm -f app para que ejecutar ./launcher start app inicie una instancia completamente nueva vinculada al puerto 8080. Verifica que docker ps muestre algo bajo “puertos” similar a:

    # docker ps
    CONTAINER ID   IMAGE                 COMMAND        CREATED          STATUS          PORTS                                                                                NAMES
    d21772a21e36   local_discourse/app   "/sbin/boot"   45 minutos atrás   Up 45 minutos   0.0.0.0:8080->80/tcp, [::]:8080->80/tcp, 0.0.0.0:8443->443/tcp, [::]:8443->443/tcp   app
    

    (Como puedes ver, dejé la directiva 443=>8443 en mi app.yml, funciona de cualquier manera.)

  • (8) Monitoreo e inicio:

    Sigue el flujo de arranque con docker logs -f app hasta que terminen las migraciones de la base de datos y los workers comiencen a procesar solicitudes. Básicamente, un montón de líneas “INFO” en rápida sucesión.

  • (9) Finalización:

    Carga tu subdominio en un navegador, haz clic en Registrarse y deja que el sistema envíe un correo de validación a tu buzón.

*) hasta que se demuestre lo contrario :wink:

Tuve que apagar mi servidor Nginx antes de la instalación. Es bueno ver que hay una bandera para omitir esta prueba, aunque :slight_smile: