Installazione di Discourse dietro reverse proxy utilizzando l'installazione raccomandata (supportata)

In questo post, ti mostrerò esattamente come eseguire discourse dietro un reverse proxy nginx. Utilizzando ancora i metodi di installazione supportati.

Requisiti:

  1. Nome di dominio valido.
  2. Certificato SSL valido.
  3. Voci DNS valide che puntano al nome di dominio.
  4. Server di posta elettronica o provider SMTP valido e funzionante.
  5. Reverse Proxy Nginx funzionante e capacità di raggiungere l’istanza e creare il certificato SSL per un uso futuro.
  6. VM o container LxC in grado di eseguire docker.

Per questa guida utilizzerò la mia istanza come esempio, con tutte le funzionalità attive, backup, aggiornamenti, ecc. Testato per circa 2 settimane.

Specifiche della mia VM Discourse:

  • CPU: 4 Core
  • RAM: 6 GB
  • Swap: 8 GB (file di swap SSD)
  • Archiviazione: 50 GB (SSD)
  • Sistema operativo: Ubuntu 22.04.3

Puoi usare il minimo, ma durante i test. Discourse utilizza facilmente 2 GB. L’utilizzo inattivo è di circa 1,48 GB su 6 GB.

NOTA: Questa installazione utilizza il reverse proxy per creare i certificati SSL. È possibile utilizzare certbot se preferito.

PASSO 1:

Scarica l’ultima versione di Ubuntu Server da Get Ubuntu Server | Download | Ubuntu

PASSO 2:

  1. Installa Ubuntu Server sul template VM/LxC
    1.1 Assicurati che Ubuntu sia aggiornato con tutti i pacchetti del server.
  2. Utilizza i seguenti comandi per installare tutti i pacchetti richiesti:
apt update -y && apt upgrade -y && apt wget curl zip git docker.io nginx -y && reboot

PASSO 3:
Installazione di Discourse. Seguendo la Guida per principianti discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub

Accedi al tuo server tramite SSH ed esegui semplicemente quanto segue:

sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
chmod 700 containers

Dopo aver completato quanto sopra. Puoi quindi eseguire ./discourse-setup

Segui tutti i passaggi e inseriscili correttamente, poiché ciò sarà fondamentale per un’installazione di successo.
I passaggi richiederanno quanto segue; esempio dalla guida di configurazione:

Lascia che l’installazione venga eseguita, potrebbe richiedere del tempo a seconda della tua connessione Internet e delle specifiche del server. L’installazione completa ha richiesto circa 5-8 minuti utilizzando la mia configurazione VM.

PASSO 4:

Una volta completata l’installazione, vedrai il comando di avvio che il container docker sta utilizzando e l’ID del container generato (hash).

NOTA: Poiché ti trovi dietro un proxy tramite la WAN, vedrai un errore 502 e poiché il container utilizza la rete di docker. Non sarà raggiungibile dalla WAN o dalla LAN, a meno che tu non ti connetta alla rete 172.17.0.1/16, di cui non avremo bisogno.

Verifica che l’installazione sia stata completata e che il container docker sia in esecuzione utilizzando:

docker ps

Dovresti ottenere il seguente output.

CONTAINER ID   IMAGE                 COMMAND        CREATED      STATUS       PORTS     NAMES
XXXXXX   local_discourse/app   \"/sbin/boot\"   6 days ago   Up 7 hours             app

PASSO 5:
Aggiornamento del file app.yml per adattarlo alla configurazione del reverse proxy.

Utilizza il tuo editor di testo preferito per aprire /var/discourse/container/app.yml
Sostituisci/commenta le seguenti righe: (questo sarà gestito dal Nginx locale)

  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"

Immediatamente dopo #- "templates/web.letsencrypt.ssl.template.yml" aggiungi quanto segue:

- "templates/web.socketed.template.yml"

Quindi commenta la sezione expose poiché discourse utilizzerà ora un websocket, infine nginx sarà in grado di avviarsi poiché libererà le porte 80 e 443 richieste localmente.

#expose:
# - "80:80" # http
# - "443:443" # https

Ora, per forzare Discourse a fornire solo link con HTTPS, aggiungi quanto segue nella sezione env:

# FORCE SSL
DISCOURSE_FORCE_HTTPS: true

Ora, per far funzionare finalmente le cose, dovrai ricostruire l’app. Utilizzando quanto segue:

cd /var/discourse
./launcher rebuild app

Lascia che venga eseguito e completato. Per verificare se ha avuto successo, assicurati che il comando di esecuzione di docker sia visualizzato o semplicemente esegui docker ps e vedrai il container in esecuzione.

PASSO 6:

Abilitazione di Nginx e configurazione del sito predefinito per puntare al container docker. Consentendo al Reverse proxy di accedere al container utilizzando nginx locale.

Esegui quanto segue:

systemctl enable nginx && systemctl start nginx

Per verificare se è in esecuzione. Prova ad accedere alla pagina di destinazione predefinita di nginx utilizzando il tuo browser e l’IP locale.
ES:

http://10.10.0.4

Dovresti ricevere una pagina di congratulazioni da Nginx.

PASSO 7:
Aggiornamento della configurazione predefinita alla seguente:
Prima svuota il file di configurazione:

echo "" > /etc/nginx/sites-available/default

Utilizza il tuo editor di testo per aprire il file di configurazione e aggiungere quanto segue:
NOTA: Aggiorna server_name con il tuo dominio e ssl_certificate, ssl_certificate_key con la posizione del tuo certificato SSL e della chiave.
Certbot può essere utilizzato, ma io semplicemente faccio rsync il mio certificato e la mia chiave dal mio reverse proxy.

server {
    listen 80; listen [::]:80;
    server_name add.yourdomain.com;
    server_tokens off;
    return 301 https://$host$request_uri;
}
# Default server configuration
#
server {
	# SSL configuration
	#
	server_tokens off;
	listen 443 ssl default_server;
	listen [::]:443 ssl default_server;

    server_name add.yourdomain.com;
	ssl_certificate /etc/ssl/certs/your_ssl_cert.bundle;
	ssl_certificate_key /etc/ssl/private/your_ssl_cert.key;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
	ssl_prefer_server_ciphers on;
	location / {
		proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock;
		proxy_set_header Host $http_host;
		proxy_http_version 1.1;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_set_header X-Real-IP $remote_addr;
	}
}

Salva il nuovo file predefinito ed esegui systemctl restart nginx.

PASSO 8:

Apri il tuo browser e vai al dominio del tuo forum https://somedomain.com e sarai accolto dalla seguente pagina.

Ecco fatto, tutto fatto. Puoi quindi seguire i passaggi per registrarti e avviare il tuo forum/community :).

PASSO AGGIUNTIVO:

Manutenzione post-installazione
Suggeriamo vivamente di attivare gli aggiornamenti automatici di sicurezza per il tuo sistema operativo. In Ubuntu usa dpkg-reconfigure -plow unattended-upgrades

Per supporto puoi semplicemente usare questa community, per il Nginx locale puoi chiedere assistenza su questo post.

10 Mi Piace

Questo è fantastico. Grazie.

Una cosa che vorrei vedere come miglioramento di questa guida è la possibilità di servire asset statici tramite nginx.

Attualmente, tutte le richieste statiche vanno al worker nella configurazione sopra. Sto ancora cercando di capire come aggirare questo problema, pubblicherò un aggiornamento se lo scoprirò.

Puoi specificare quali file statici?

Stai forse parlando delle pagine statiche 404, 302, 500 di nginx o delle pagine statiche di Discourse?

Ci ho guardato un po’ e ho scoperto che il reindirizzamento per le pagine 404 funziona. L’unica pagina che non riesco a impostare sembra essere la pagina di errore 500.

Puoi essere un po’ più specifico in modo che io sappia esattamente cosa sto cercando. :slight_smile:

Questa guida è eccellente. Sono riuscito a seguirla tutta finché non sono arrivato al caricamento del sito web. Ricevo un errore di “troppi reindirizzamenti”. Quando uso l’IP, Discourse si carica bene, ma non riesco a superare il problema dei reindirizzamenti. Così vicino.

Qualsiasi aiuto sarebbe apprezzato.

Grazie.

Qualcuno sa come posso risolvere questo problema? Il sito funziona, ma noto questi errori nel file error.log del container nginx. Ho utilizzato un reverse proxy configurato secondo queste istruzioni sopra.

Guardando in /etc/nginx/conf.d/discourse.conf nel container, vedo

upstream discourse { server 127.0.0.1:3000; }

Dovrebbe essere qualcosa del tipo?:

upstream discourse { http://unix:/var/discourse/shared/standalone/nginx.http.sock; }

Guardando in /var/log/nginx nel container, vedo errori come:

2025/02/09 21:00:21 [error] 69#69: *1 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xxx.xxx, server: _, request: "POST /message-bus/b39980c2387e4750bc1e320cb6195424/poll?dlp=t HTTP/1.1", upstream: "http://127.0.0.1:3000/message-bus/b39980c2387e4750bc1e320cb6195424/poll?dlp=t", host: "discourse.xxxx.com"

2025/02/09 21:00:23 [error] 67#67: *3 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xxx, server: _, request: "GET /chat/api/me/channels HTTP/1.1", upstream: "http://127.0.0.1:3000/chat/api/me/channels", host: "discourse.xxxx.com"

2025/02/09 21:00:23 [error] 70#70: *5 connect() failed (111: Connection refused) while connecting to upstream, client: xx.xx.xx.xxx, server: _, request: "POST /message-bus/d95b6999d26242f28f4875732b195440/poll HTTP/1.1", upstream: "http://127.0.0.1:3000/message-bus/d95b6999d26242f28f4875732b195440/poll", host: "discourse.xxxx.com"

Grazie!

Hai seguito correttamente il passaggio 5? Sembra che tu non stia usando un socket.

Sì, sto usando un socket sul proxy inverso locale all’esterno del container e ho seguito il passaggio 5 in app.yml.

/var/discourse/containers# grep web.socketed.template.yml app.yml
  - "templates/web.socketed.template.yml"

/var/discourse/containers# grep templates/web.ssl.template.yml app.yml
  #  - "templates/web.ssl.template.yml"

/var/discourse/containers# grep templates/web.letsencrypt.ssl.template.yml app.yml
  #  - "templates/web.letsencrypt.ssl.template.yml"

/var/discourse/containers# grep http app.yml

#  - "80:80"   # http
#  - "443:443" # https

/var/discourse/containers# grep DISCOURSE_FORCE_HTTPS app.yml
DISCOURSE_FORCE_HTTPS: true
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
  ## Uncomment the next line to enable the IPv6 listener
  #- "templates/web.ipv6.template.yml"
  - "templates/web.ratelimited.template.yml"
  ## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #  - "templates/web.ssl.template.yml"
  #  - "templates/web.letsencrypt.ssl.template.yml"
  - "templates/web.socketed.template.yml"
## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
#expose:
#  - "80:80"   # http
#  - "443:443" # https

Ho esaminato questo: Discourse working with jwilder /nginx proxy & acme-companion

ma non riesco a capirlo in relazione al mio problema…