Actualización fallida con: Falta el outlet Nginx "before-server"... discourse_docker no es compatible con la versión de Discourse elegida

Tengo un servidor Discourse para el cual ./launcher rebuild app resulta en:

FAILED
--------------------
Pups::ExecError: grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'El outlet Nginx \"before-server\" falta. Esta versión de discourse_docker no es compatible con la versión de Discourse elegida.' ; exit 1 ) falló con el retorno #<Process::Status: pid 300 exit 1>
Ubicación del fallo: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec falló con los parámetros {"cmd"=>["cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf", "rm /etc/nginx/sites-enabled/default", "mkdir -p /var/nginx/cache", "grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'El outlet Nginx \"before-server\" falta. Esta versión de discourse_docker no es compatible con la versión de Discourse elegida.' ; exit 1 )", "grep -q 'outlets/server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'El outlet Nginx \"server\" falta. Esta versión de discourse_docker no es compatible con la versión de Discourse elegida.' ; exit 1 )", "grep -q 'outlets/discourse' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'El outlet Nginx \"discourse\" falta. Esta versión de discourse_docker no es compatible con la versión de Discourse elegida.' ; exit 1 )", "mkdir -p /etc/nginx/conf.d/outlets/before-server", "touch /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf", "touch /etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf", "mkdir -p /etc/nginx/conf.d/outlets/server", "touch /etc/nginx/conf.d/outlets/server/10-http.conf", "touch /etc/nginx/conf.d/outlets/server/20-https.conf", "touch /etc/nginx/conf.d/outlets/server/30-offline-page.conf", "mkdir -p /etc/nginx/conf.d/outlets/discourse", "touch /etc/nginx/conf.d/outlets/discourse/20-https.conf", "touch /etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf"]}
falló el arranque con el código de salida 1
** FALLÓ EL ARRANQUE ** por favor, desplázate hacia arriba y busca mensajes de error anteriores, puede haber más de uno.
./discourse-doctor puede ayudar a diagnosticar el problema.
727ce99bf07d8a65ba26b70f4515a2b6dab493ca00f436098de95e70604b6d6b

El código está actualizado:

git status
En la rama main
Tu rama está actualizada con 'origin/main'.

nada que confirmar, árbol de trabajo limpio

Intenté ejecutar ./discourse-doctor pero resultó en el mismo error.

El servidor en cuestión está ejecutando Ubuntu:

cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.2 LTS"

Con el último Docker:

apt info docker-ce
Paquete: docker-ce
Versión: 5:28.3.2-1~ubuntu.24.04~noble
Prioridad: opcional
Sección: admin
Mantenedor: Docker <support@docker.com>
Tamaño-Instalado: 90.1 MB
Pre-Depende: init-system-helpers (>= 1.54~)
Depende: containerd.io (>= 1.6.24), docker-ce-cli, iptables, libc6 (>= 2.34), libsystemd0
Recomienda: apparmor, ca-certificates, docker-ce-rootless-extras, git, pigz, procps, xz-utils
Sugiere: cgroupfs-mount | cgroup-lite, kmod
Conflicto: docker (< 1.5~), docker-engine, docker.io
Reemplaza: docker-ce-cli (< 5:28.0.0), docker-engine
Página principal: https://www.docker.com
Tamaño-Descarga: 19.6 MB
APT-Manual-Instalado: sí
APT-Sources: https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
Descripción: Docker: el motor de contenedores de aplicaciones de código abierto
 Docker es un producto para que construyas, envíes y ejecutes cualquier aplicación como un
 contenedor ligero
 .
 Los contenedores Docker son agnósticos tanto de hardware como de plataforma. Esto significa
 que pueden ejecutarse en cualquier lugar, desde tu portátil hasta la instancia de cómputo en la nube más grande y
 todo lo intermedio, y no requieren que uses un lenguaje, framework o sistema de empaquetado en particular. Eso los convierte en excelentes bloques de construcción
 para implementar y escalar aplicaciones web, bases de datos y servicios backend sin
 depender de una pila o proveedor en particular.

N: Hay 34 registros adicionales. Por favor, usa el interruptor '-a' para verlos.

¿Alguien tiene alguna sugerencia? ¿Necesito editar manualmente la configuración de Nginx en el contenedor en ejecución para evitar esto o algo así?

He intentado degradar la base de código de docker_manager a la versión anterior al último commit del 10 de julio de 2025:

su - discourse
cd /var/discourse/
./launcher enter app
su - discourse
cd /var/www/discourse/plugins/docker_manager
git checkout d91016c
exit
exit
./launcher rebuild app

Pero eso no marcó la diferencia.

Acabo de hacer una reconstrucción sin ningún problema. ¿Hay otros errores además de los que incluiste? ¿Qué informa free -h?

No es un problema de espacio en disco:

df -h
Sistema de archivos  Tamaño  Usado  Disp.  % Uso Montado en
tmpfs           588M  1.1M  587M   1% /run
/dev/sda2       118G   79G   34G  71% /
tmpfs           2.9G     0  2.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           588M   12K  588M   1% /run/user/1001

El servidor no tiene swap pero tiene 6 GB de RAM:

free -h
               total        usado        libre      compartido  búfer/caché   disponible
Mem:           5.7Gi       793Mi       1.2Gi       1.0Mi       4.1Gi       5.0Gi
Swap:             0B          0B          0B

¿Crees que se necesita un disco de swap?

A continuación se muestra la configuración de Nginx (/etc/nginx/conf.d/discourse.conf) que contiene el contenedor, no había ninguna referencia a outlets/before-server:

# Los tipos MIME adicionales que deseas que nginx maneje van aquí
types {
    text/csv csv;
}

upstream discourse { server 127.0.0.1:3000; }

proxy_cache_path /var/nginx/cache keys_zone=one:10m max_size=200m;

# ver: https://meta.discourse.org/t/x/74060
proxy_buffer_size 8k;

# Si vas a usar Puma, usa estos:
#
# upstream discourse {
#   server unix:/var/www/discourse/tmp/sockets/puma.sock;
# }


# intentar preservar el proto, debe estar en el contexto http
map $http_x_forwarded_proto $thescheme {
  default $scheme;
  https https;
}

log_format log_discourse '[$time_local] \"$http_host\" $remote_addr \"$request\" \"$http_user_agent\" \"$sent_http_x_discourse_route\" $status $bytes_sent \"$http_referer\" $upstream_response_time $request_time \"$sent_http_x_discourse_username\"';

limit_req_zone $binary_remote_addr zone=flood:10m rate=12r/s;
limit_req_zone $binary_remote_addr zone=bot:10m rate=200r/m;
limit_req_status 429;
limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;
server {
  listen 80;
  return 301 https://discourse.example.org$request_uri;
}
server {


  access_log /var/log/nginx/access.log log_discourse;

  listen 443 ssl;
http2 on;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

ssl_certificate /shared/ssl/discourse.example.org.cer;
ssl_certificate /shared/ssl/discourse.example.org_ecc.cer;

ssl_certificate_key /shared/ssl/discourse.example.org.key;
      proxy_ignore_headers "Set-Cookie";
      proxy_hide_header "Set-Cookie";

      proxy_cache one;
      proxy_cache_key $uri;
      proxy_cache_valid 200 7d;
      proxy_cache_valid 404 1m;
      proxy_set_header Connection "";

      proxy_pass https://avatars.discourse.org/;
      break;
    }

    # necesitamos desactivar el buffering para el message bus
    location /message-bus/ {
      proxy_set_header X-Request-Start "t=${msec}";
      proxy_set_header Host $http_host;
      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 $thescheme;
      proxy_http_version 1.1;
      proxy_buffering off;
      proxy_pass http://discourse;
      break;
    }

    # esto significa que cada archivo en public se intenta primero
    try_files $uri @discourse;
  }

  location /downloads/ {
    internal;
    alias $public/;
  }

  location @discourse {
add_header Strict-Transport-Security 'max-age=31536000'; # recuerda el certificado durante un año y conéctate automáticamente a HTTPS para este dominio

  limit_conn connperip 20;
  limit_req zone=flood burst=12 nodelay;
  limit_req zone=bot burst=100 nodelay;
    add_header Referrer-Policy 'no-referrer-when-downgrade';
    proxy_set_header Host $http_host;
    proxy_set_header X-Request-Start "t=${msec}";
    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 $thescheme;
    proxy_pass http://discourse;
  }

}

Así que instalé vim y dos2unix y edité los archivos para añadir la línea:

include conf.d/outlets/before-server/*.conf;

Y detuve e inicié Nginx y luego salí del contenedor y ejecuté ./launcher rebuild app de nuevo, pero se devolvió el mismo error:

FAILED
--------------------
Pups::ExecError: grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The "before-server" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 ) failed with return #<Process::Status: pid 300 exit 1>
Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.3.0/lib/pups/exec_command.rb:131:in `spawn'
exec failed with the params {"cmd"=>["cp $home/config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf", "rm /etc/nginx/sites-enabled/default", "mkdir -p /var/nginx/cache", "grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"before-server\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/server' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"server\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "grep -q 'outlets/discourse' /etc/nginx/conf.d/discourse.conf || ( >&2 echo 'The \\\"discourse\\\" Nginx outlet is missing. This version of discourse_docker is not compatible with the chosen Discourse version.' ; exit 1 )", "mkdir -p /etc/nginx/conf.d/outlets/before-server", "touch /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf", "touch /etc/nginx/conf.d/outlets/before-server/30-ratelimited.conf", "mkdir -p /etc/nginx/conf.d/outlets/server", "touch /etc/nginx/conf.d/outlets/server/10-http.conf", "touch /etc/nginx/conf.d/outlets/server/20-https.conf", "touch /etc/nginx/conf.d/outlets/server/30-offline-page.conf", "mkdir -p /etc/nginx/conf.d/outlets/discourse", "touch /etc/nginx/conf.d/outlets/discourse/20-https.conf", "touch /etc/nginx/conf.d/outlets/discourse/30-ratelimited.conf"]}
bootstrap failed with exit code 1
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one.
./discourse-doctor may help diagnose the problem.
b18ed0cbde3a34dfe76ea066657ece16c5a063ff18627d4a7e4b9787268917c0

Así que reinicié el contenedor (./launcher start app) para comprobarlo:

grep -q 'outlets/before-server' /etc/nginx/conf.d/discourse.conf
echo $?
0

Entonces, ¿por qué falla si la inclusión de Nginx está presente?

Hay muchas diferencias entre /var/www/discourse/config/nginx.sample.conf y /etc/nginx/conf.d/discourse.conf — ¿debería intentar reemplazar el archivo con la muestra y editarlo para actualizar el nombre de dominio?

Actualización

Anteriormente, la interfaz web de Discourse no permitía actualizaciones, decía que las actualizaciones debían hacerse usando la CLI, sin embargo, ahora sí las permite (¿por qué es eso?) así que he actualizado discourse_docker usando la Interfaz Web:

Y también discourse:

Así que este problema está resuelto sin embargo lo que, si es que hice algo, para resolverlo es un misterio… :woman_shrugging:

He rastreado el problema — fue causado por el plugin discourse-images-guardian de @mbcahyono que necesitaba actualizar el archivo nginx.sample.conf, lo he hecho y he creado una pull request para solucionarlo.

¡Fusionado! Gracias por la PR.

No tuve la oportunidad de probarlo, así que confío en ti en esta :slight_smile:

1 me gusta

Gracias @mbcahyono, hice algunas pruebas básicas y parece que funciona… ¡Sin embargo, este es este problema — anular las URL de las imágenes del sitio ya no funciona, ¿alguna idea de cómo solucionarlo?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.