# Configurazione di distribuzione di Discourse secondo l'opinione di MKJ

**URL:** https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355
**Category:** Sysadmins
**Tags:** explanation, install
**Created:** [9 Giugno 2021, 11:34pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355 "2021-06-09T23:34:00Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [9 Giugno 2021, 11:34pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/1 "2021-06-09T23:34:01Z")

</div>

Ho gestito un forum Discourse con una quantità sostanziale di contenuti e molte immagini negli ultimi anni. [Maker Forums](https://forum.makerforums.info/) ha oltre 100 GB di immagini e più di 400.000 post, di cui una quantità significativa è stata importata, principalmente da Google+, e il resto è stato creato sul sito. Questo post descrive gli elementi di come ho alla fine configurato Maker Forums e, successivamente, alcune altre istanze Discourse. È ciò che avrei voluto sapere quando ho iniziato, e che ho usato per aiutare altri a evitare alcune delle stesse insidie per le loro istanze Discourse.

Tempo di ampliare il pubblico.

> ⚠ **Attenzione:** Se non ti senti a tuo agio a lavorare come amministratore di sistema Linux, questa guida probabilmente non fa per te. Potrei nemmeno essere consapevole di tutti i modi in cui presuppone conoscenze su Linux. Se leggere questo ti sembra illuminante, potresti essere il pubblico target. Se ti sembra confuso, probabilmente non sei il pubblico target. Se ti sembra un lavoro, valuta di pagare CDCK o @pfaffman per gestire Discourse per te; sanno quello che stanno facendo. Oppure inizia con un [sito gratuito discourse.group](https://www.discourse.org/free) e poi paga per ciò in cui cresci. ⚠
> 
> ⚠ Come se non bastasse: ho più esperienza con Linux che con Discourse. Le mie opinioni non sono coperte da garanzia. Se seguire i miei consigli causa la rottura di qualcosa di tuo (il tuo forum Discourse, il tuo sistema host o il tuo cuore), ti restano entrambi i pezzi, con tutti i bordi taglienti. Non ho intenzione di fornire alcun tipo di supporto per i contenuti di questo post. ⚠

Ho l’intenzione (ma non prometto) di mantenere questo documento aggiornato con le mie pratiche relative alle istanze Discourse che partecipiamo a mantenere. È scritto in forma di consiglio, ma intendo principalmente come consiglio a me stesso e a qualsiasi amministratore che erediti distribuzioni Discourse di cui mi sono occupato. Altrimenti, dovresti considerarlo come un punto di partenza per _la tua propria ricerca_ per determinare come desideri distribuire Discourse.

# Configurazione del sistema

Usa un OS derivato da CentOS o Ubuntu LTS. Qualsiasi cosa che supporti Docker può probabilmente essere fatta funzionare, ma ho usato questi due.

## Docker

Sono un utente Fedora. Sono stato il primo Fedora Project Lead a Red Hat, e preferirei molto di più eseguire Discourse su Podman perché ritengo che il suo modello di sicurezza sia preferibile a quello di Docker. Tuttavia, le distribuzioni Discourse sono supportate solo su Docker, e sarai [un vero pioniere se provi a eseguire su qualsiasi altra cosa](https://meta.discourse.org/t/any-interest-in-podman/118182?u=mcdanlj). (Potrebbe, un giorno, funzionare con Podman usando podman-compose se docker-compose venisse mai supportato.)

Ora che Docker supporta cgroups v2, puoi installare le build ufficiali di Docker su un sistema derivato da CentOS:

```plaintext
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install --allowerasing docker-ce docker-ce-cli

```

(Includi `--allowerasing` a causa di un conflitto con `podman`, `runc` e `buildah` che potrebbero essere già installati; devono essere rimossi per installare docker.)

```plaintext
systemctl enable --now docker

```

Ho testato questo con AlmaLinux 9.

## Sicurezza

Questa sezione non ha davvero a che fare con Discourse _in sé_, ma fa parte della mia normale pratica di sicurezza. **Non consentire l’accesso shell solo con password a qualsiasi sistema sulla rete, incluso una VM che esegue Discourse.** Configura l’accesso basato su SSH usando una chiave SSH crittografata con passphrase e configura il server ssh sulla tua VM per non consentire l’accesso con password.

```plaintext
laptop$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/.../.ssh/id_rsa):
Enter passphrase (empty for no passphrase): UNA FRASE LUNGA
Enter same passphrase again: UNA FRASE LUNGA
Your identification has been saved in .ssh/id_rsa
Your public key has been saved in .ssh/id_rsa.pub

```

Le distribuzioni Linux sono normalmente configurate per ricordare la passphrase in memoria, quindi devi digitarla solo una volta per avvio. Windows non è così comodo; potresti considerare [l’uso di Pageant con PuTTY](https://www.digitalocean.com/community/tutorials/how-to-use-pageant-to-streamline-ssh-key-authentication-with-putty) per fare lo stesso.

Prima, valida che l’SSH in arrivo funzioni senza password. Solo dopo aver fatto questo, sul server, modifica il file /etc/ssh/sshd\_config e trova la riga `PasswordAuthentication`. Impostala su `no` per disabilitare l’accesso con password in arrivo.

```plaintext
PasswordAuthentication no

```

### Firewall

Dovrai lasciare le porte 80 e 443 generalmente aperte per letsencrypt per generare e rinnovare i tuoi certificati SSL, anche prima che il tuo Discourse sia aperto al pubblico.

Se stai usando firewalld, questi comandi realizzeranno questo:

```plaintext
firewall-cmd --add-service http --add-service https --zone public
firewall-cmd --runtime-to-permanent

```

## Dispositivo e file system separati

Rendi /var/discourse/shared un **dispositivo** separato con il proprio file system, con 20 GB di spazio più almeno il doppio dello spazio di cui hai bisogno per le immagini; aggiungi più spazio se userai prometheus. Se il dispositivo sarà facile da espandere in seguito (come LVM o qualsiasi storage a blocchi cloud come AWS elastic block storage) puoi monitorarlo e farlo crescere come necessario; altrimenti sii generoso all’inizio. Se stai usando un dispositivo di storage a blocchi di rete, non mettere una tabella delle partizioni su di esso. Usarlo senza una tabella delle partizioni renderà più facile l’espansione; non dovrai modificare una tabella delle partizioni. In molti casi potrai espandere senza alcun downtime del sistema.

Su Maker Forums, questo è un dispositivo di storage a blocchi di rete attaccato alla VM su cui Maker Forums è in esecuzione. Su un altro forum Discourse, è un Volume di Storage a Blocchi Digital Ocean. In Amazon, questo sarebbe AWS Elastic Block Storage. Sul mio sistema di test che esegue una VM KVM sotto libvirt su Fedora, è un volume LVM sull’host Fedora esportato alla VM AlmaLinux come disco virtuale. In ogni caso, potevo creare una nuova VM, copiare i file chiave su di essa, fermare la vecchia VM, attaccare il volume /var/discourse/shared alla nuova VM e tornare operativo in pochi minuti. Questo rende gli aggiornamenti del sistema operativo sulla VM a rischio relativamente basso.

Assicurati di iniziare con almeno 25 GB sul file system root della tua VM, non includendo spazio per /var/discourse/shared. Questo sarà usato per tutti i container docker, e il launcher discourse fallirà se meno di 5 GB sono liberi in qualsiasi momento. Vuoi anche molto spazio disponibile per gli aggiornamenti di sistema. Se non hai abbastanza spazio su disco, è difficile recuperare da questo.

Nella configurazione del sito, imposta `force_https` ma presta attenzione agli avvertimenti. Configuralo in test, prima di rendere pubblico un sito Discourse. Nota che anche con `force_https` hai bisogno della porta 80 aperta, sia per reindirizzare a SSL sulla porta 443 che per rinnovare il tuo certificato SSL letsencrypt. (Tuttavia, se stai usando cloudflare, usa la sua funzione invece; si riferisce che non è compatibile con `force_https` in Discourse.)

## Configurazione del kernel

Redis (uno dei componenti chiave su cui Discourse è costruito) [raccomanda fortemente di disabilitare le huge pages trasparenti quando si usa la persistenza su disco](https://redis.io/docs/management/optimization/latency/#latency-induced-by-transparent-huge-pages) (che Discourse fa), e permetto anche l’overcommit della memoria.

```plaintext
echo 'w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
w /sys/kernel/mm/transparent_hugepage/defrag - - - - never' > /etc/tmpfiles.d/thp.conf
systemd-tmpfiles --create
echo 'vm.overcommit_memory=1' > /etc/sysctl.d/90-vm_overcommit_memory.conf
sysctl --system

```

# Installazione di Discourse

Mentre l’[installazione predefinita](https://github.com/discourse/discourse/blob/main/docs/INSTALL-cloud.md) è un singolo container, questo rende ogni aggiornamento, raccomandato mensilmente, tipicamente un downtime di 10-15 minuti se fatto dalla riga di comando, che è necessario per alcuni aggiornamenti, inclusi quelli che aggiornano gli strumenti su cui Discourse è costruito, per sicurezza o nuove funzionalità, o quando l’aggiornamento live dall’interfaccia utente fallisce per qualsiasi motivo. Puoi ridurre quel downtime nella pratica con l’installazione a due container.

## Installazione a due container

Inizia la configurazione con due container.

```plaintext
./discourse-setup --two-container --skip-rebuild
${EDITOR:-nano} containers/data.yml
./launcher rebuild data
# la mia preferenza è usare app.yml ma potresti restare con web_only.yml, leggi il testo
mv containers/web_only.yml containers/app.yml
${EDITOR:-nano} containers/app.yml
./launcher rebuild app

```

Questo rende il downtime di sistema necessario ogni pochi mesi molto breve, raramente percettibile; molti utenti non se ne accorgeranno affatto se non cliccano o scorrono oltre i contenuti durante il downtime. Questo rende più facile applicare la maggior parte degli aggiornamenti di sicurezza; è solo un’interruzione piuttosto che circa 15 minuti di ricostruzione di tutto. Il seguente processo funziona per la maggior parte degli aggiornamenti e tipicamente dà circa 30-90 secondi di downtime, dipendendo principalmente dalle prestazioni del sistema host e dall’insieme di plugin installati.

```plaintext
cd /var/discourse
git pull
./launcher bootstrap app
./launcher destroy app && ./launcher start app
./launcher cleanup

```

Non ritardare tra le invocazioni bootstrap e destroy/start. Raramente (forse una o due volte all’anno nella pratica), le migrazioni del database fatte vicino alla fine della fase bootstrap causeranno errori più o meno seri da presentare agli utenti dell’app, a causa del codice più vecchio che accede al database aggiornato.

Questo **significa** che quando aggiorni Discourse, devi anche controllare se aggiornare anche il container dati, ma questo è raramente richiesto (tipicamente aspetta una o due volte all’anno). A seconda dei contenuti dei tuoi container dati e app e della velocità del sistema, questo risulterà tipicamente in un downtime tra 5 e 20 minuti.

```plaintext
cd /var/discourse
git pull
./launcher stop app
./launcher rebuild data
./launcher rebuild app

```

Per saperne di più su quando aggiornare il container dati, vedi:

> [@Migra rapidamente verso contenitori separati per il web e i dati](https://meta.discourse.org/t/how-to-migrate-quickly-to-separate-web-and-data-containers/153355#what-to-do-on-future-updates-4?u=mcdanlj):
>
> warning Attenzione: Se non ti senti a tuo agio nell’operare come amministratore di sistemi Linux e non hai esperienza con i container Docker, passare a un deployment multi-container ti causerà difficoltà. Sia lo staff che i volontari ti chiederanno appropriatamente di tornare a un deployment singolo autonomo, gestito interamente dallo script launcher. Se passi a un deployment multi-container e il tuo sistema si rompe a causa di ciò, è probabile che tu ti trovi nella situazione di dover gest…

(Nelle mie distribuzioni personali, ho scelto personalmente di chiamare il container `web_only` `app` sia perché è più facile da digitare che perché rende la maggior parte delle istruzioni più facili da seguire. Questo è non standard ma continuo ad apprezzare la facilità d’uso. Tuttavia, è stato lavoro extra, e funziona per me perché so cosa sta succedendo. Se questo ti sembra male, resta con il `web_only` predefinito invece per una distribuzione multi-container.)

Nota che in qualche punto in futuro, Docker potrebbe costringerti a fare una migrazione a una nuova configurazione per connettere i tuoi container:

> [@Passaggio da container standalone a container web e dati separati](https://meta.discourse.org/t/how-to-move-from-standalone-container-to-separate-web-and-data-containers/29413/95?u=mcdanlj):
>
> Sembra una buona idea. A meno che qualcuno non mi anticipi, verificherò la possibilità di creare una PR per passare alle reti e/o ai socket (che alcuni preferiscono comunque) e di realizzare una guida per convertire un’installazione esistente nella nuova configurazione.

Se hai 4 GB o più di memoria, o più CPU, leggi i consigli a:

> [@Configurare Discourse Docker su server con più RAM e CPU](https://meta.discourse.org/t/how-to-configure-discourse-docker-on-higher-end-servers/18569?u=mcdanlj):
>
> Quando si installa Discourse su un’istanza con 4 GB o più, è consigliabile considerare quanto segue: Monitorare la configurazione Se si sceglie di utilizzare una configurazione di fascia alta, si consiglia vivamente di impostare il monitoraggio utilizzando un servizio come [Prometheus](https://prometheus.io/), [Datadog](https://www.datadoghq.com/) o [New Relic](https://newrelic.com/). Sarà necessario analizzare i risultati delle modifiche alla configurazione per raggiungere una configurazione ottimale. La configurazione predefinita di Discourse Docker include 3 web worker I…

## Programma di aggiornamento

Monitora il tag #release-notes (Clicca su #release-notes e clicca sulla campana in alto a destra; uso “Watching First Post”) e/o aggiungi `https://meta.discourse.org/tag/release-notes.rss` al tuo feed RSS per sapere quando ci sono rilasci. Leggi le note di rilascio prima di aggiornare. Se c’è un cambiamento nel database, le note di rilascio lo menzioneranno. Evidenzieranno anche i rilasci che contengono aggiornamenti di sicurezza. Leggi tutte le note di rilascio anche se salti l’aggiornamento effettivo a una versione; se non leggi le note di rilascio per un rilascio che aggiorna il database, potresti perdere le istruzioni di aggiornamento del database nelle note di rilascio che non hai letto.

## Posta

La posta è ancora uno dei modi chiave per mantenere le connessioni tra le persone. Configura la posta in uscita e in entrata per far lavorare la posta per te. Se hai problemi vedi:

> [@Risoluzione problemi email su una nuova installazione di Discourse](https://meta.discourse.org/t/troubleshooting-email-on-a-new-discourse-install/16326?u=mcdanlj):
>
> You just installed Discourse via [the install guide](https://github.com/discourse/discourse/blob/main/docs/INSTALL.md), but email doesn’t seem to work. Unfortunately this means you can’t log in as an admin to finalize the install. cry Let’s troubleshootize! Try the doctor woman_health_workerIf you run ./discourse-doctor it will check several ways that your mail configuration might be broken, and offer advice. Try that first. Did you enter email settings correctly? The simplest way is to run ./discourse-setup again. Did you enter everything correctly? B…

### Continua a cercare

Maker Forums ha visto visitatori occasionali che sono stati via per lunghi periodi prima di tornare. Di default, Discourse smette di inviare email di digest dopo un anno. Considera di impostare `suppress_digest_email_after_days` su qualcosa di più lungo dei 365 giorni predefiniti se vuoi incoraggiare i visitatori occasionali a tornare quando vedono qualcosa di nuovo e interessante. L’ho reso sostanzialmente più lungo per Maker Forums per supportare i visitatori occasionali che si tengono aggiornati. Leggere le email di digest è un modo valido per “nascere” su un forum, e non sai mai quando qualcosa potrebbe accendere l’interesse di qualcuno nel contribuire.

Similmente, di default, gli utenti non privilegiati che non hanno interagito molto (livello di fiducia 0 senza post) sono eventualmente eliminati dopo 730 giorni di non accesso. Imposta “pulisci utenti inattivi dopo giorni” a 0 per disabilitare l’eliminazione degli utenti, se vuoi che siano in grado di nascere leggendo email di digest indefinitamente.

Considera di aggiungere il plugin [yearly review](https://github.com/discourse/discourse-yearly-review.git) che una volta all’anno, genererà un post come [2020: The Year in Review](https://meta.discourse.org/t/2020-the-year-in-review/174719?u=mcdanlj) **e alla fine lo invierà via email ai tuoi utenti inattivi** che potrebbe incoraggiarli a rinnovare la partecipazione.

> [@Revisione annuale di Discourse](https://meta.discourse.org/t/discourse-yearly-review-plugin/105713?u=mcdanlj):
>
> | | |-|-| |:discourse2: | Riepilogo | Discourse Yearly Review crea un argomento il 1° gennaio che riassume l’attività del forum dell’anno precedente. (Vedi i nostri esempi qui su Meta - #year-in-review) |:hammer\_and\_wrench: | Link al repository | [https://github.com/discourse/discourse-yearly-review](https://github.com/discourse/discourse-yearly-review) |:open\_book: | Guida all’installazione | [Come installare i plugin in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157)Configurazione iniziale Vai alla pagina /admin/plugins e clicca sul pulsante delle impostazioni gear Impostazioni …

### Container ricevitore di posta

Configura un terzo container come ricevitore di posta. Assicura l’elaborazione dei rimbalzi, rende la tua elaborazione dei rimbalzi indipendente dal provider di posta in uscita e ti dà l’opzione di risposta via email.

> [@Configura la consegna diretta delle email in entrata per siti self-hosted con Mail-Receiver](https://meta.discourse.org/t/direct-delivery-incoming-email-for-self-hosted-sites/49487?u=mcdanlj):
>
> Discourse is all about enabling civilized discussion. While plenty of people like a web interface, e-mail is still the “hub” of many people’s online lives. That’s why sending e-mail is so important, and when you’re sending e-mail, you really want to be able to receive it, too. There are several reasons why: If e-mails “bounce” (they can’t be delivered for some reason), you need to know about that. Repeatedly sending e-mails that bounce will get your e-mails flagged as spam. Receiving e-ma…

Assicurati di avere [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework) configurato per fidarti del tuo mittente email; minimamente, una politica come `v=spf1 +mx -all` se invii e ricevi attraverso lo stesso MX, ma più specifico potrebbe essere più fidato come protezione contro lo spam. Considera anche [DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail).

Se usi lo stesso nome host per ricevere email, dovresti davvero terminare SSL fuori dal tuo container come per una “pagina offline” (vedi sotto) e dovrai [mappare i tuoi certificati certbot nel container](https://meta.discourse.org/t/direct-delivery-incoming-email-for-self-hosted-sites/49487?u=mcdanlj#integrating-with-external-nginx-6) e riavviare il container dopo aver eseguito certbot.

## Termina le connessioni SSL degli utenti fuori dal container

Ci sono due scelte per terminare SSL fuori dal container, entrambe delle quali portano vantaggi sostanziali rispetto a terminare dentro il container. Configura una di esse dopo aver completato con successo `discourse-setup` e aver bootstrapato il tuo forum.

### Nginx esterno

Usa nginx in esecuzione sul sistema host, piuttosto che solo in un container, sia per ospitare una pagina di manutenzione, che per supportare la registrazione degli indirizzi IPv6 se il tuo host ha supporto IPv6. (Altrimenti, tutte le connessioni IPv6 saranno registrate come provenienti da un indirizzo RFC1918 interno associato alla tua interfaccia di rete virtuale docker locale.) Questa configurazione presenterà una pagina di manutenzione temporanea durante la maggior parte delle operazioni di manutenzione che alla fine reindirizzerà alla pagina che un utente stava guardando.

> [@Aggiungere una pagina offline da visualizzare quando Discourse si sta ricostruendo o avviando](https://meta.discourse.org/t/adding-an-offline-page-when-rebuilding/45238?u=mcdanlj):
>
> warning This guide is intended for advanced users, who are already using nginx outside the docker container. By following this guide you make your setup more complicated and will lose some speed benefits like HTTP2 if you’re not running Ubuntu 16.04 or later. Proceed with caution! When Discourse is rebuilding or starting up, your users will usually either see an error message from their browser… …or a not-so-nice 502 error message from Nginx: If you’re a perfectionist …

Nota che le istruzioni su quella pagina (attualmente) suggeriscono di installare un pacchetto chiamato `letsencrypt` ma ora è normalmente chiamato `certbot` invece. Se segui le istruzioni su quella pagina per usare `--certonly`, non avrai bisogno del plugin nginx per certbot, ma installare il plugin nginx è un altro meccanismo. Su derivati CentOS:

```plaintext
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install certbot python3-certbot-nginx
systemctl enable --now certbot-renew.timer

```

Assicurati che certbot riavvii nginx e il container ricevitore di posta in modo da non finire con browser o email che bloccano il traffico con il tuo sito a causa della continuazione dell’uso di un certificato vecchio e scaduto.

```plaintext
# systemctl edit certbot-renew

```

Per un sistema senza un ricevitore di posta, ho aggiunto le due righe:

```plaintext
[Service]
ExecStartPost=/bin/systemctl reload nginx

```

Su un sistema dove sto usando un container ricevitore di posta separato che condivide anche il certificato dal sistema:

```plaintext
[Service]
ExecStartPost=/bin/systemctl reload nginx
ExecStartPost=/bin/sh -c 'cd /var/discourse && ./launcher restart mail-receiver'

```

Se stai usando SELinux, i container Ubuntu non sono configurati per etichettare il file `nginx.http.sock` con `httpd_sys_content_t` per consentire a nginx esterno di accedervi. Hai due scelte.

La prima è eseguire nginx in modalità permissiva, rimuovendo la protezione SELinux per esso: `semanage permissive -a httpd_t`

Tuttavia, questo rimuove la protezione SELinux da ciò che è probabilmente il servizio più rilevante! Per mantenere SELinux abilitato, dovrai permettere a nginx di accedere alle pagine di errore e passare dal proxying su un socket di dominio unix a una porta (che è alcuni µs più lento, ma non dovrebbe essere percettibile dai tuoi utenti).

Prima, esegui questi comandi per permettere a nginx di accedere alle pagine di errore:

```plaintext
semanage fcontext -a -t httpd_sys_content_t /var/www
restorecon -R -v /var/www

```

Poi nel tuo app.yaml, commenta o rimuovi `- "templates/web.socketed.template.yml"`, esponi la porta 80 come una porta diversa sulla macchina locale e ricostruisci il container.

```plaintext
expose:
  - "8008:80" # http

```

Non usare `https` qui — hai terminato SSL in nginx esterno, e l’intestazione `X-Forwarded-Proto` dice a Discourse che la richiesta è arrivata via https. Assicurati che la porta 8008 (o qualsiasi altra porta che hai scelto) non sia esposta pubblicamente dalle tue impostazioni del firewall.

Poi esegui questo comando per permettere a nginx di connettersi alla rete al container:

```plaintext
setsebool -P httpd_can_network_connect 1

```

Poi modifica la tua configurazione nginx esterna da proxying via `nginx.http.sock` a `http://127.0.0.1:8008` (o la tua porta scelta) e cancella l’intestazione predefinita `Connection: close`, in modo che nginx esterno non debba stabilire una nuova connessione IP per ogni richiesta.

```plaintext
...
  location / {
    proxy_pass http://127.0.0.1:8008;
    proxy_set_header Host $http_host;
    proxy_http_version 1.1;
    # Disable default "Connection: close"
    proxy_set_header "Connection" "";
...

```

Rimuovere `web.socketed.template.yml` ha anche rimosso l’invocazione `real_ip`, quindi aggiungila di nuovo. Assicurati che l’intervallo di indirizzi IP che usi abbia senso; il default di Docker è usare lo spazio degli indirizzi RFC1918 172.16\* che non sono instradati su internet pubblico per politica. Aggiungi al tuo file app.yml qualcosa come questo nella sezione run, selezionando uno o più degli spazi degli indirizzi RFC1918 o qualsiasi altra cosa appropriata per la tua distribuzione:

```yaml
run:
  - file:
     path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
     chmod: 644
     contents: |
       real_ip_recursive on;
  - file:
     path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
     chmod: 644
     contents: |
       real_ip_header X-Forwarded-For;
  - file:
     path: /etc/nginx/conf.d/outlets/server/set-real-ip-from.conf
     chmod: 644
     contents: |
       set_real_ip_from 192.168.0.0/16;
       set_real_ip_from 172.16.0.0/12;
       set_real_ip_from 10.0.0.0/8;

```

Questo è richiesto per il rate limiting per funzionare correttamente, così come per attribuire indirizzi IP di registrazione e ultimo uso per gli utenti.

Per ulteriori informazioni:

> [@Gestione della "catena di fiducia" dell'IP reale dell'utente finale](https://meta.discourse.org/t/handling-the-chain-of-trust-of-the-end-users-real-ip/406372?u=mcdanlj):
>
> Contesto Discourse deve essere consapevole dell’indirizzo IP reale dell’utente finale. Tuttavia, un utente finale non si connette mai direttamente a Discourse, poiché è sempre presente uno o più server web upstream (nginx in esecuzione nel container Discourse). Pertanto, abbiamo bisogno di un modo per trasmettere queste informazioni a Discourse in modo affidabile. L’intestazione x-forwarded-for è la soluzione. In questo argomento descriverò i meccanismi specifici per gestire correttamente ques…

### Servizio esterno

Non ho configurato Fastly o Cloudflare davanti a Discourse, ma altri l’hanno fatto, e a differenza di nginx esterno in esecuzione sull’host, possono permetterti di servire una pagina di manutenzione mentre il sistema host è completamente giù, come quando si riavvia durante un aggiornamento di sistema sul tuo host. Se questo vale la pena per te, ecco come farlo:

> [@Accelerazione CDN del sito completo per Discourse](https://meta.discourse.org/t/full-site-cdn-acceleration-for-discourse/21467?u=mcdanlj):
>
> [Fastly](http://www.fastly.com/), [CloudFlare](https://www.cloudflare.com) e alcune altre CDN offrono una modalità in cui accelerano i contenuti dinamici. In sintesi, si punta l’indirizzo IP del dominio alla CDN e la CDN deciderà in modo intelligente come gestire la richiesta. I contenuti statici possono essere facilmente serviti dalla cache I contenuti dinamici possono essere instradati al sito. Ciò offre alcuni vantaggi rispetto alla sola spedizione di risorse statiche, trattati in [questa guida alle CDN](https://meta.discourse.org/t/enable-a-cdn-for-your-discourse/14857). È possibile optare per lo “[shielding](http://www.fastly.com/products/origin-shield/)” …

## Non affrettarti con gli upload S3

Sii molto sicuro che vuoi sempre [usare S3 (o equivalente) per le immagini caricate](https://meta.discourse.org/t/setting-up-file-and-image-uploads-to-s3/7229?u=mcdanlj) prima di abilitare `enable_s3_uploads` durante la configurazione, o migrare ad esso in seguito. Sii consapevole che l’uso di S3 (`s3_endpoint`) con il suo CDN associato (`s3_cdn_url`) per le immagini risulterà anche nel servire javascript via quel CDN. La migrazione da S3 allo storage locale non è supportata e non ci sono piani concreti per implementarlo in questo momento. È una “porta a senso unico” che non può nemmeno essere annullata da un backup e ripristino completo. Se usi S3 o simile, non usare Digital Ocean Spaces invece di S3. Ci sono riferimenti qui su meta a non essere affidabile.

Ho spostato il mio sito a servire immagini attraverso Digital Ocean Spaces e il suo CDN associato presto, e ho dovuto scrivere centinaia di righe di codice personalizzato per migrare di nuovo allo storage locale, causando danni minori alla mia istanza Discourse nel processo, a causa della “porta a senso unica” non essere ben compresa.

Per ulteriori informazioni:

> [@Problemi con Migrate\_from\_s3](https://meta.discourse.org/t/migrate-from-s3-problems/119064?u=mcdanlj):
>
> When migrating from S3 to local storage, we see a number of issues. The main issue is that the migrate\_from\_s3 rake task is not taking the Uploads table as a starting point, but the posts. This causes it to skip a lot of uploads which are being left on S3. uploads used as logo’s because they are not referenced in a post uploads for avatars because they are not referenced in a post uploads that are (for some reason) referenced by their CDN URL in raw because they do not match [the regex](https://github.com/discourse/discourse/blob/master/lib/tasks/uploads.rake#L130) that is…

Non hai bisogno di abilitare gli upload S3 per usare un CDN per il tuo Discourse. Considera di usare un CDN indipendente (es. Cloudflare, CloudFront, Fastly, GCS CDN) davanti a un Discourse che gestisce le proprie immagini. È la mia comprensione indiretta che l’avvertimento su Cloudflare non essere raccomandato è dovuto a [“Rocket Loader” che modifica JavaScript](https://meta.discourse.org/search?q=cloudflare%20broken); e che in questo momento, finché non usi “Rocket Loader” funziona correttamente.

> [@Abilita una CDN per il tuo Discourse](https://meta.discourse.org/t/enable-a-cdn-for-your-discourse/14857?u=mcdanlj):
>
> Quindi desideri utilizzare una CDN per velocizzare l’accesso globale alle risorse comuni sul tuo forum Discourse? Potresti voler fare il grande passo e seguire le istruzioni su [Set up file and image uploads to S3](https://meta.discourse.org/t/setting-up-file-and-image-uploads-to-s3/7229) (vedi anche [Configure an S3 compatible object storage provider for uploads](https://meta.discourse.org/t/configure-an-s3-compatible-object-storage-provider-for-uploads/148916)). Se desideri una CDN senza la complessità aggiuntiva di S3 e l’avere due CDN, questa è la guida che fa per te. La CDN ridurrà parte del carico sul tuo server consentendo alla CDN di servire tali risorse in modo…

## Impostazioni Discourse per la moderazione

Su qualsiasi sito dove la moderazione è attiva, considera fortemente la configurazione `enable_whispers` che permette ai moderatori e agli amministratori di parlare di un argomento in linea. Inoltre, i moderatori di categoria hanno ricevuto più capacità nelle versioni recenti di Discourse. Vale la pena essere consapevoli di `enable_category_group_moderation` se hai esperti in argomenti diversi con le loro categorie, o se hai categorie funzionalmente separate come per il supporto.

La geolocalizzazione può essere utile quando si cerca di capire se un account è legittimo.

> [@Configura MAXMIND per le ricerche IP inverse](https://meta.discourse.org/t/configuring-maxmind-for-reverse-ip-lookups/173941?u=mcdanlj):
>
> Cos’è MAXMIND e perché dovrei volerlo utilizzare? Discourse utilizza [MAXMIND](https://www.maxmind.com/en/home) per fornire informazioni geografiche per le ricerche IP inverse. Senza il database di Maxmind, vedrai qualcosa di simile a questo: Oppure potresti aver notato questo messaggio apparire mentre ricompili il tuo container: Il download del database IP di MaxMind richiede un ID account e una chiave di licenza Imposta DISCOURSE\_MAXMIND\_ACCOUNT\_ID e DISCOURSE\_MAXMIND\_LICENSE\_KEY. Consulta https:/…

La funzione [Discourse Templates](https://github.com/discourse/discourse-templates) è davvero utile per i moderatori. Ti permette di collaborare su risposte comuni. Abbiamo alcune decine su Maker Forums. Ha più funzionalità del plugin precedente “Canned Responses” che sostituisce.

La funzione [User Notes](https://github.com/discourse/discourse-user-notes) aiuterà i moderatori a condividere note sugli utenti. Puoi metterle in uso per cose come:

- “Tieni d’occhio questo utente, potrebbero essere malintenzionati perché …”
- “Mentre questo comportamento sembra sospetto, ho validato che questo è un utente legittimo da …”
- “Sto già avendo una conversazione con questo utente per affrontare le preoccupazioni, altri moderatori non devono accumulare.”

## Accessibilità delle informazioni

Il plugin [Discourse Solved](https://github.com/discourse/discourse-solved.git) non solo marca i problemi risolti in modo che i visitatori del sito possano identificarli più facilmente, ma capisco che potrebbe anche prioritizzare i risultati di ricerca google.

Le informazioni pubbliche sono più accessibili delle informazioni private. Su Maker Forums, la nostra [FAQ scoraggia fortemente i messaggi personali e ricorda a tutti che i messaggi personali non sono veramente privati](https://forum.makerforums.info/faq#publicforum). Tuttavia, di default, gli utenti potrebbero vedere il messaggio:

> Hai risposto a _utente_ 3 volte, sapevi che potevi inviare loro un messaggio personale invece?

Se vuoi davvero incoraggiare gli utenti a andare ai messaggi personali, suggerisco di andare su Admin → Customize → Text e cambiare il template `get_a_room` per correggere la virgola splice.

Se, come Maker Forums, vuoi mantenere la conversazione pubblica per beneficiare tutti, Admin → Settings → Other → `get_a_room_threshold` può essere impostato più alto, come 1000000.

Similmente, se hai un forum che fornisce aiuto, il `max_replies_in_first_day` default 10 potrebbe spingere nuovi utenti in una conversazione che chiede aiuto nei messaggi personali quando esauriscono il loro budget di risposte. Considera di aumentare questa impostazione per evitare di spingere le conversazioni nei messaggi personali.

## Connetti gli utenti, costruisci una comunità

Alcuni plugin possono aiutare a connettere gli utenti tra loro.

Se il tuo forum non ha troppi utenti simultanei, considera il plugin Who’s Online per dare alle persone più senso di connessione. Potresti voler limitare la visualizzazione agli utenti connessi, possibilmente solo quelli che hanno raggiunto almeno il livello di fiducia 1. Puoi usarlo solo per aggiungere presenza flair (`whos_online_avatar_indicator`) agli avatar impostando `whose_online_minimum_display` molto alto e `whos_online_hide_below_minimum_display` true. Questo può essere utile per i forum di supporto per supportare e incoraggiare domande e risposte rapide mentre si aiutano gli utenti a risolvere i problemi.

Tuttavia, un senso di presenza può tagliare in entrambe le direzioni. Un utente che è online in un orario diverso dalla maggior parte degli utenti del forum potrebbe sentirsi solo, o il forum potrebbe sembrare una “città fantasma” per loro.

> [@Chi è online su Discourse](https://meta.discourse.org/t/whos-online-plugin-discourse-whos-online/52345?u=mcdanlj):
>
> discourse2Riepilogo Discourse Who’s Online mostra un elenco degli utenti attualmente attivi sul sitohammer_and_wrenchLink al repository [https://github.com/discourse/discourse-whos-online](https://github.com/discourse/discourse-whos-online)open_bookGuida all’installazione [Come installare i plugin in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157)Funzionalitàinformation_source Pensa attentamente prima di installare questo plugin. Discourse è progettato per discussioni asincrone e un elenco degli utenti online può essere dannoso per alcune comunità. …

Se hai utenti in molti paesi e vuoi che abbiano indizi su quando gli altri sono più probabilmente disponibili, considera il plugin National Flags, e incoraggia gli utenti a impostare una bandiera nazionale nel loro profilo.

> [@Bandiere Nazionali (fork)](https://meta.discourse.org/t/national-flags-fork/384423?u=mcdanlj):
>
> information_source Questo è un fork di [https://meta.discourse.org/t/national-flags/55969?u=chapoi](https://meta.discourse.org/t/national-flags/55969?u=chapoi) (che non sembra più mantenuto) ed è principalmente una versione aggiornata per renderlo compatibile con le ultime richieste di glimmer/ember/discourse. È quindi quasi funzionalmente identico, con solo alcune piccole modifiche (vedi sotto). Non voglio dirottare l’argomento originale, nel caso in cui l’autore torni slight_smileinformation_sourceRiepilogo Mostra una bandiera nazi…

Uno difficile è la traduzione. Sarebbe comodo aiutare le persone a comunicare quando non parlano la stessa lingua, ma attualmente (al momento della scrittura) non ci sono servizi di traduzione con livelli di servizio gratuiti. Se scegli di pagare per servizi di traduzione, puoi abilitare la traduzione con il plugin Discourse Translator.

> [@Traduttore Discourse](https://meta.discourse.org/t/discourse-translator/32630?u=mcdanlj):
>
> discourse2Riepilogo Discourse Translator traduce i post su Discourse utilizzando le API di traduzione di Microsoft, Google o Yandex.hammer_and_wrenchLink al repository [https://github.com/discourse/discourse-translator](https://github.com/discourse/discourse-translator)open_bookGuida all’installazione [Come installare i plugin in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157)Funzionalità Ogni post viene tradotto una sola volta per ogni lingua, risparmiando moneybagNota che il rilevamento della lingua viene …

# Backup

Per i file di sistema, considera di fare backup almeno di:

- `/var/discourse/containers` (per i dettagli di configurazione di discourse)
- `/var/www` (per le pagine di errore)
- `/etc/ssl` (per la configurazione di letsencrypt, per evitare di dover bootstrapare certbot come parte del ripristino di un backup; altrimenti devi commentare la porzione SSL della tua configurazione nginx mentre stai bootstrapando; questo funziona solo se mantieni i backup recenti perché i certificati hanno validità breve)
- `/etc/systemd/system/backup-uploads.service` (per fare backup delle immagini a S3)
- `/usr/local/bin/mc` (minio-client come strumento di backup immagini, se scegli di usarlo)
- `/root/.mc` (configurazione per backup immagini con minio-client)
- `/root/.ssh` (autenticazione sessione SSH in arrivo)

Alcuni di questi file potresti fare backup controllandoli in Git e spingendoli da qualche parte fuori sito. Se i file che controlli in Git includono segreti (come password del database), definitely non spingerli a un repository pubblico. In alternativa, potresti scriptare la copia fuori dal sistema e il controllo in Git su un sistema di supervisione che controlli. Scripta questo sufficientemente frequentemente per mantenere i tuoi backup di `/etc/ssl` freschi.

L’obiettivo è avere backup sia in caso di disastro che per avere registro di cambiamenti in caso di errore.

Un’alternativa migliore per la maggior parte di questi file è mantenere le copie canoniche altrove, e usare uno strumento come Ansible per mantenere la configurazione sul sistema, che rende altrettanto facile aggiornare dopo un backup. Ma se stai per fare questo, probabilmente l’hai capito senza che te lo dicessi!

## Configurazione Discourse per backup

- Fai backup delle miniature con `include_thumbnails_in_backups`. Un ripristino senza miniature richiede molto tempo per rigenerarle. Se il tuo sito non ha molte grafiche, le miniature occupano spazio insignificante. Se il tuo sito è ricco di grafiche, rigenerare le miniature potrebbe richiedere giorni. Mentre le miniature vengono rigenerate, le notifiche email saranno disabilitate. In ogni caso, non ha senso omettere le miniature dai backup.

- Non includere immagini nei backup se hai molte immagini. Questo renderà i backup lenti e ingombranti. Fallo backup separatamente. Se fai backup delle immagini dopo il backup del database, i tuoi backup saranno coerenti.

- Organizza per i backup di andare fuori sito in qualche modo.

Questa pagina mostra come configurare backup del database a S3 o qualcosa come S3:

> [@Configura backup automatici per Discourse](https://meta.discourse.org/t/configure-automatic-backups-for-discourse/14855?u=mcdanlj):
>
> bookmark Questa guida spiega come configurare i backup automatici per Discourse, incluse le opzioni di archiviazione su server locali e archiviazione compatibile con S3. Scopri come configurare i backup automatici per la tua piattaforma Discourse. Questa guida copre la configurazione dei backup automatici, l’archiviazione su server locali o archiviazione compatibile con S3 e la gestione delle opzioni di conservazione dell’archiviazione come Amazon Glacier. Configurazione dei backup automa…

### Fai backup con restic

Configura discourse per fare backup al file system, poi fai backup dal file system a un target di backup remoto con [restic](https://restic.net/). Ecco una ricetta di esempio.

```shell
# dnf install restic
# mkdir /var/restic
# mkdir /opt/backup
# cd /opt/backup
# cat > backup <<EOF
#!/usr/bin/bash

set -e
. /opt/backup/backup-config

restic --cache-dir=/var/restic \
	backup \
	/etc \
	/root \
	/var/discourse \
	/opt/backup \
	--exclude /var/discourse/shared/data/postgres_data

restic --cache-dir=/var/restic forget \
	--prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
EOF
# chmod +x backup

```

Questi dettagli varieranno a seconda del target restic. Non tutti utilizzano le variabili di ambiente AWS, quindi leggi la documentazione di restic.

```shell
# cat > backup-config <<EOF
### Questi dettagli dipendono dal target restic che configuri, quindi modificali
export AWS_ACCESS_KEY_ID=la-tua-chiave
export AWS_SECRET_ACCESS_KEY=la-tua-chiave-secreta
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY=vedi-la-documentazione-restic
EOF
# {$EDITOR:-nano} /root/restic-password

```

Dovrai conservare una copia di ciò che inserisci in `/root/restic-password`, altrimenti non potrai leggere i backup! Usa il tuo vault per le password.

Infine, crea alcuni servizi, inizializza il repository restic e imposta un timer in modo che i backup abbiano inizio.

```shell
# cat > /etc/systemd/system/backup.service <<EOF
[Unit]
Description=Backup su target remoto
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
StandardOutput=file:/var/log/backup.out
StandardError=file:/var/log/backup.err
WorkingDirectory=/var/discourse
ExecStart=/opt/backup/backup

[Install]
WantedBy=multi-user.target
EOF
# cat > /etc/systemd/system/backup.timer <<EOF
[Unit]
Description=Backup di sistema regolari

[Timer]
Persistent=true
OnCalendar=00/4:30:00
Unit=backup.service

[Install]
WantedBy=timers.target
EOF

# systemctl daemon-reload
# . /opt/backup/backup-config
# restic init
# /opt/backup/backup
# systemctl enable backup.timer

```

Dopo questo processo, dovresti essere in grado di vedere che hai creato il tuo backup iniziale.

```shell
# restic snapshots

```

Ho utilizzato con successo i backup restic realizzati in questo modo per spostare un server Discourse da un sistema a un altro utilizzando il comando `restic restore`.

### Backup immagine streaming con minio

Come alternativa a Restic, mentre i backup del database possono essere archiviati su S3, non esiste un backup immagine S3 separato dal servizio delle immagini da S3. Un’alternativa è utilizzare [minio-client](https://docs.min.io/docs/minio-client-complete-guide) per copiare le immagini su qualsiasi storage simile a S3. Questo può includere molti target simili a S3, tra cui S3 e minio, ma [non DigitalOcean Spaces](https://github.com/minio/mc/issues/3067) perché è costruito sopra il filesystem Ceph che non implementa l’API `ListObjectsV2` nello stesso modo in cui lo fa S3.

In S3, crea un bucket che blocchi l’accesso pubblico ( **Permissions** → **Block public access** è il modo più semplice per ottenere questo risultato in AWS).

Installa minio-client (mc) in qualche modo. Ecco un modo.

```plaintext
curl https://dl.min.io/client/mc/release/linux-amd64/mc > /usr/local/bin/mc && chmod +x /usr/local/bin/mc

```

Configura minio-client con un alias chiamato `backup` utilizzando un comando simile a questo:

```plaintext
# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4
# mc mirror /var/discourse/shared/standalone/uploads backup/UPLOADS-BACKUP-BUCKET

```

Quindi crea un servizio /etc/systemd/system/backup-uploads.service come questo

```plaintext
[Unit]
Description=Sincronizzazione backup remoto quasi in tempo reale degli upload di discourse
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=600
User=root
ExecStart=/usr/local/bin/mc mirror --overwrite -a --watch /var/discourse/shared/app/uploads backup/UPLOADS-BACKUP-BUCKET

[Install]
WantedBy=multi-user.target

```

Nota che `UPLOADS-BACKUP-BUCKET` qui dovrebbe essere un bucket diverso dal `s3_backup_bucket` in cui configuri Discourse per caricare i backup del database. Inoltre, nota che il percorso sarà `/var/discourse/shared/web_only/uploads` se utilizzi la distribuzione multi-container standard.

```plaintext
# systemctl enable backup-uploads
# systemctl start backup-uploads
# journalctl -fu backup-uploads

```

Carica un’immagine di test e assicurati di vedere le righe per il backup riuscito delle immagini originali e ottimizzate. Control-C uscirà dalla modalità follow in journalctl.

## Recupero

Non ho mai dovuto testare questo piano fino a questo momento. Questo riepilogo potrebbe omettere qualcosa.

- Ripristina tutti i file backup in generale
- Avvia nginx (ora la tua pagina di manutenzione sarà visibile)
- Esegui una distribuzione normale di Discourse utilizzando i file ripristinati in /var/discourse/containers
- Installa minio-client in /usr/local/bin/mc se non lo hai ripristinato dai backup
- Se non hai fatto il backup di `/root/mc`, configura l’alias di backup `# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4`
- `# mc cp backup/UPLOADS-BACKUP-BUCKET /var/discourse/shared/app/uploads`
- Ripristina il backup del database più recente; ti consiglio di [Restore a backup from the command line](https://meta.discourse.org/t/restore-a-backup-from-command-line/108034)
- Solo **dopo** aver confermato che il sito è operativo, riconfigura il backup degli upload su S3 come documentato sopra.

## Backup postgresql streaming

In futuro, potrei creare, testare e fornire una configurazione per abilitare l’uso di [archiviazione WAL continua](https://www.postgresql.org/docs/current/continuous-archiving.html) per trasmettere backup Postgres quasi istantanei con minio-client utilizzando il comando `archive-command` in postgresql, simile ai backup upload streaming.

> [@Streaming di backup con minio-client?](https://meta.discourse.org/t/streaming-backups-with-minio-client/192924?u=mcdanlj):
>
> Non mi piace la configurazione di backup più frequente, che avviene solo una volta al giorno. Sembra che in caso di disastro si rischi di perdere molto del lavoro meticoloso di molte persone. Tuttavia, non voglio configurare un cluster con HA; è troppo pesante in termini di risorse per il mio caso d’uso. Voglio semplicemente avere un alto grado di fiducia nel poter recuperare quasi tutto ciò che è stato scritto sul mio Discourse, anche se ci vuole un po’ di tempo. Questo Discourse è una risorsa …

# Monitoraggio delle prestazioni

Ci sono almeno due approcci per il monitoraggio delle prestazioni.

## Container Prometheus

Configura prometheus, mettendo i log di prometheus in /var/discourse/shared/prometheus se lo stai eseguendo sullo stesso sistema. I file di Prometheus possono crescere molto, e non vuoi che riempiano il filesystem root; probabilmente vuoi anche portarli con te se ti sposti su un sistema host più recente (sia aggiornando a una VM più grande che a una VM con un’installazione di sistema operativo più recente).

> [@Install Prometheus plugin + Prometheus on your server](https://meta.discourse.org/t/install-prometheus-plugin-prometheus-on-your-server/72786?u=mcdanlj):
>
> The new [Discourse Prometheus](https://meta.discourse.org/t/prometheus-exporter-plugin-for-discourse/72666) makes Discourse spit out data that Prometheus can consume and then make cool graphs. Check out the description linked above, if you haven’t already. That data doesn’t help much if you don’t have Prometheus installed. You can head over to [https://prometheus.io/](https://prometheus.io/) to download, install, and configure the Prometheus, or, for $100 I will: install the Prometheus plugin on your Discourse instance Install Prometheus in a Docker container on your server Configure Prometheus …

Se distribuischi prometheus sul sistema Discourse (o ovunque else su internet pubblico), configura la sicurezza davanti ad esso. Installato in quel modo, un’opzione sarebbe la configurazione nginx come questa:

```plaintext
  location /prometheus/ {
    auth_basic "Prometheus";
    auth_basic_user_file /etc/nginx/prometheus-htpasswd;
    proxy_pass http://localhost:9090/;
  }

```

## Sysstat

Se Prometheus è troppo, considera l’uso di sysstat invece.

- `dnf install sysstat` (o `apt install sysstat` su debian e derivati)
- `systemctl enable --now sysstat`
- `systemctl enable --now sysstat-collect.timer`
- `systemctl enable --now sysstat-summary.timer`
- `systemctl edit sysstat-collect.timer` e cambia `OnCalendar=*:00/10` in `OnCalendar=*:00/2`
- Se /etc/default/sysstat esiste, cambia `false` in `true`

Dopo questo, il comando `sar` può dirti se stai esaurendo le risorse di tanto in tanto.

# Altre Risorse

Ecco una discussione complementare (e più compatta) sull’uso di Discourse internamente come forma primaria di comunicazione interna.

> [@Perché usare Discourse internamente per la tua azienda o team al posto di Slack (utilizzo da 4 anni)](https://meta.discourse.org/t/why-you-should-use-discourse-internally-for-your-company-team-instead-of-slack-4-years-use-case/296983?u=mcdanlj):
>
> Utilizziamo Discourse come strumento principale per la comunicazione, la conservazione dei record, la documentazione della ricerca, lo strumento di diario di laboratorio da oltre 4 anni. Sosterrò che la maggior parte delle aziende trarrebbe grande beneficio dall’avere Discourse come strumento di comunicazione principale anziché catene di Slack e email e WhatsApp. Si riduce a questo: Se credi che ci sia del valore nelle conversazioni tra dipendenti per future riflessioni, allora hai bisogno di …

---

<div class="post-metadata">

### Author: ![valsha](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/valsha/32/230631_2.png) [@valsha](https://meta.discourse.org/u/valsha)
#### Post date: [20 Settembre 2021, 12:05pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/2 "2021-09-20T12:05:40Z")

</div>

Ciao, grazie per questa guida

> [@mcdanlj](#):
>
> ha oltre 100 GB di immagini e oltre 400.000 post

Quali sono attualmente la CPU (core) e la RAM?  
Quali sono le impostazioni attuali:

```plaintext
  db_shared_buffers: "xGB"
  db_work_mem: "xMB"
  UNICORN_WORKERS:

```

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [20 Settembre 2021, 12:26pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/3 "2021-09-20T12:26:32Z")

</div>

> [@valsha](#):
>
> Quali sono le tue attuali CPU (core) e RAM?

2 vCPU (L5640 Xeon), 4 GB di RAM — ma grazie all’importazione massiccia, abbiamo contenuti per utente simultaneo superiori rispetto a un Discourse tipico costruito interamente in modo organico. Raramente abbiamo più di 5 utenti simultanei.

> [@valsha](#):
>
> Quali sono le tue impostazioni attuali:

Attualmente non ho impostato `db_work_mem` in data.yml, ma sembra che sia impostato a 10 MB in /etc/postgresql/13/main/postgresql.conf. Nel mio file `data.yml` ho impostato `db_shared_buffers: "768MB"`, ma ora vedo che in /etc/postgresql/13/main/postgresql.conf nel mio contenitore dati c’è scritto `shared_buffers = 512MB`, il che mi sorprende. Apparentemente non ho ricreato il mio contenitore dati dopo l’ultima modifica. 🙄 Ho apportato la modifica di configurazione prima di aggiungere Prometheus (che utilizza più memoria), quindi prima di cambiare quella impostazione probabilmente sposterò Prometheus su un’altra istanza del server.

Nell’app, ho impostato `UNICORN_WORKERS: 4`

---

<div class="post-metadata">

### Author: ![jaffadog](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jaffadog/32/236329_2.png) [@jaffadog](https://meta.discourse.org/u/jaffadog)
#### Post date: [17 Novembre 2021, 12:58am UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/4 "2021-11-17T00:58:30Z")

</div>

Grazie @mcdanlj per tutte queste chicche. Qualche consiglio sulla manutenzione periodica/pianificata? come riavvii settimanali/mensili? o monitoraggio su/giù con riavvio automatico? Altra manutenzione periodica manuale o automatizzata?

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [17 Novembre 2021, 3:46am UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/5 "2021-11-17T03:46:51Z")

</div>

@jaffadog Tieni d’occhio il tag #release-notes (è la campana in alto a destra; io uso “Watching First Post”) e/o aggiungi `https://meta.discourse.org/tag/release-notes.rss` al tuo feed RSS per sapere quando ci sono rilasci. Questo avviene tipicamente mensilmente per l’app, il che copre il riavvio mensile. Non riavvio più frequentemente secondo un programma. Inoltre:

> [@mcdanlj](#):
>
> Questo **significa** che quando aggiorni Discourse, devi anche verificare se aggiornare anche il contenitore dei dati, ma questo è raramente necessario (tipicamente una o due volte all’anno). Per saperne di più su quando aggiornare i dati, vedi:
> 
> [Migrate quickly to separate web and data containers](https://meta.discourse.org/t/how-to-migrate-quickly-to-separate-web-and-data-containers/153355#what-to-do-on-future-updates-4?u=mcdanlj)

Se usi letsencrypt e mail\_receiver, probabilmente dovresti configurarlo per riavviare mail\_receiver dopo aver ottenuto un nuovo certificato.

Questo è tutto ciò che mi viene in mente al momento. Grazie per aver chiesto, e ho incorporato come seguire #release-notes e maggiori dettagli sul riavvio nel testo principale. Penso che ora sia tutto completamente coperto nel post originale.

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [31 Gennaio 2022, 2:42am UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/6 "2022-01-31T02:42:34Z")

</div>

Ho aumentato le istruzioni di aggiornamento per recuperare gli aggiornamenti in /var/discourse al fine di cambiare la versione dell’immagine di base, perché guardando [Update base image for polkit vulnerability](https://meta.discourse.org/t/update-base-image-for-polkit-vulnerability/216305?u=mcdanlj) mi sono reso conto che non essere espliciti su questo passaggio potrebbe essere fuorviante. In precedenza lo consideravo una di quelle cose che fanno parte della documentazione di base. Lo script `launcher` contiene un riferimento specifico alla versione dell’immagine di base e finché non esegui `git pull` costruirai su un’immagine di base più vecchia e non eseguirai ciò che è stato testato. (Cerca `image=` in cima al file.)

> [@mcdanlj](#):
>
> ```plaintext
> cd /var/discourse
> git pull
> ./launcher bootstrap app
> ./launcher destroy app && ./launcher start app
> ./launcher cleanup
> 
> ```

---

<div class="post-metadata">

### Author: ![Ed\_S](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ed_s/32/134015_2.png) [@Ed\_S](https://meta.discourse.org/u/Ed_S)
#### Post date: [10 Giugno 2022, 3:01pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/7 "2022-06-10T15:01:40Z")

</div>

> [@mcdanlj](#):
>
> Per impostazione predefinita, Discourse smette di inviare email di riepilogo dopo un anno.

È peggio di così: è configurato per impostazione predefinita per eliminare gli account di livello 0 inattivi dopo un certo periodo. Nel mio caso, non era affatto quello che volevo! Controlla “pulisci utenti inattivi dopo giorni” e impostalo a zero, o a un numero molto grande.

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [10 Giugno 2022, 3:17pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/8 "2022-06-10T15:17:41Z")

</div>

Ho esaminato la questione, ma per quanto ho capito significa che non hanno mai risposto al flusso “conferma il tuo indirizzo email” e quindi non avrebbero ricevuto email in ogni caso. Non credo che “inattivo” qui significhi “non accedere al sito”, ma vorrei sapere se mi sbaglio.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [10 Giugno 2022, 3:22pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/9 "2022-06-10T15:22:53Z")

</div>

> [@mcdanlj](#):
>
> significa che non hanno mai risposto al flusso “conferma il tuo indirizzo email”

No, “inattivo” non significa `attivo=falso` qui.

Significa utenti a cui si applicano tutte le seguenti condizioni:

- livello di fiducia 0
- nessun post
- non amministratore, non moderatore
- ultima visualizzazione più di X giorni fa.

E sì, quella dicitura è in effetti confusionaria, sebbene l’impostazione lo spieghi in parte (“livello di fiducia 0 senza alcun post”).

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [11 Giugno 2022, 12:57pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/10 "2022-06-11T12:57:19Z")

</div>

In realtà stavo confondendo impostazioni diverse e avevo in mente “pulisci utenti in staging non utilizzati dopo giorni”. Avevo già impostato “pulisci utenti inattivi dopo giorni” a zero in Maker Forums molto tempo fa, e non l’avevo menzionato qui; devo essermelo perso nel mio audit delle impostazioni del sito modificate quando cercavo cose che potessero essere di interesse generale. Grazie a entrambi, @Ed_S e @RGJ! Ho aggiornato il post con un altro paragrafo sull’abilitazione del lurking. ☺

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [4 Novembre 2022, 12:21pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/11 "2022-11-04T12:21:25Z")

</div>

Ciao @mcdanlj grazie per l’ottima intuizione che condividi qui. Per quanto riguarda un’installazione a 2 container, sono confuso su come ciò offra un vantaggio nel ridurre i tempi di inattività durante gli aggiornamenti. Sulla mia installazione di prova, un aggiornamento tramite l’interfaccia GUI `/admin/upgrade#/upgrade/all` richiede diversi minuti come descrivi, ma il sito rimane operativo per gli utenti durante tutto il processo.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [4 Novembre 2022, 12:35pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/12 "2022-11-04T12:35:39Z")

</div>

Quando si deve ricostruire dalla riga di comando, l’installazione di due container consente di avviare la nuova immagine mentre quella vecchia continua a funzionare.

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [5 Novembre 2022, 8:11pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/13 "2022-11-05T20:11:14Z")

</div>

Come al solito, @pfaffman è più veloce di me e sa il fatto suo. 😃

Non faccio mai aggiornamenti dalla GUI. In questo modo, ogni volta che aggiorno, includerò tutti gli aggiornamenti di sicurezza del sistema nei container sottostanti su cui Discourse è in esecuzione. Ciò non significa che sia male usare la GUI, né è una raccomandazione per tutti gli altri. Gli aggiornamenti della GUI hanno tempi di inattività leggermente inferiori (il riavvio del container web interrompe momentaneamente il servizio, il che è uno dei diversi motivi per considerare questo insieme a nginx esterno), quindi è un compromesso e io ho preso la strada meno battuta.

Un’installazione a container singolo ha tempi di inattività più lunghi più spesso, se si aggiorna regolarmente per gli aggiornamenti di sicurezza e per gli occasionali aggiornamenti della versione del database, poiché Discourse sfrutta le nuove funzionalità di Postgresql. Senza rivedere dati effettivi, la mia sensazione è che ci sia un motivo per ricostruire questo 3-4 volte all’anno. Se tale quantità di tempi di inattività è accettabile dal tuo punto di vista, non c’è molto motivo di affrontare la complessità del deployment a 2 container.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [6 Novembre 2022, 6:48pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/14 "2022-11-06T18:48:57Z")

</div>

> [@mcdanlj](#):
>
> Come al solito, @pfaffman è più veloce di me e sa il fatto suo.

È molto gentile, ma si tratta delle **tue** opinioni. 😉

> [@mcdanlj](#):
>
> Non faccio mai aggiornamenti dalla GUI.

Neanche io. Tranne con il mio dashboard, che ha un sacco di cose in più nel container (come Ansible, e non ricordo esattamente cosa), e se qualcuno sta eseguendo un aggiornamento usando [dashboard.literatecomputing.com](http://dashboard.literatecomputing.com) e poi distruggo quel container, la sua ricostruzione viene interrotta, il che è potenzialmente problematico. Quindi ho fatto alcuni aggiornamenti di docker\_manager ultimamente, e sono piuttosto eleganti.

> [@mcdanlj](#):
>
> In questo modo ogni volta che aggiorno, includerò eventuali aggiornamenti di sicurezza del sistema nei container sottostanti su cui è in esecuzione Discourse.

Non proprio. È almeno per lo più vero che se c’è una nuova immagine di base, docker\_manager ti obbligherà a ottenerla (almeno, ci proverà).

> [@mcdanlj](#):
>
> Senza rivedere dati effettivi, la mia sensazione è che ci sia un motivo per ricostruire 3-4 volte all’anno.

È più o meno giusto. A titolo informativo, e non lo consiglio, ma ho interagito con un sacco di persone che non hanno fatto aggiornamenti per anni senza alcun problema.

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [6 Novembre 2022, 8:02pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/15 "2022-11-06T20:02:45Z")

</div>

Sì, non c’è dubbio che gli aggiornamenti in-container siano ben implementati!

> [@pfaffman](#):
>
> Non proprio. È almeno per lo più vero che se c’è una nuova immagine di base, docker\_manager ti obbligherà a ottenerla (almeno, ci proverà).

Sì, era quello che intendevo. 🎉

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [12 Gennaio 2023, 2:14pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/16 "2023-01-12T14:14:18Z")

</div>

Ciao di nuovo, grazie a entrambi per le vostre intuizioni. Quindi sto ancora cercando di decidere cosa farò per il mio setup di produzione. Capisco in teoria perché un’installazione a 2 container porterebbe a meno tempi di inattività. Ma sto ancora vedendo pochissimi tempi di inattività con il meccanismo di aggiornamento della GUI. L’ho appena cronometrato, ho avuto un aggiornamento di docker-manager e Discourse era 22 commit indietro. L’intero processo ha richiesto meno di 5 minuti e durante l’intero processo il forum era pienamente operativo. Certo, questa volta non ci sono stati aggiornamenti di PostgreSQL, ma se fosse stato necessario aggiornare anche quello, allora avrei avuto il massimo tempo di inattività anche con il metodo a 2 container, corretto? Quindi, se ho capito bene, il metodo a 2 container riduce i tempi di inattività solo quando è necessario un accesso SSH e una ricostruzione del container dell’app a causa di una modifica della configurazione (aggiunta/rimozione di plugin, ecc.)? Non prevedo frequenti modifiche alla mia configurazione di produzione, quindi non vedo alcuna potenziale riduzione dei tempi di inattività nel mio caso. O devo anche accedere via SSH e ricostruire i container per applicare certi tipi di aggiornamenti di funzionalità/sicurezza?

---

<div class="post-metadata">

### Author: ![mcdanlj](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mcdanlj/32/131829_2.png) [@mcdanlj](https://meta.discourse.org/u/mcdanlj)
#### Post date: [12 Gennaio 2023, 4:32pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/17 "2023-01-12T16:32:40Z")

</div>

Va bene.

> [@rahim123](#):
>
> se fosse necessario aggiornare anche quello, allora starei guardando il tempo massimo di inattività anche con il metodo dei 2 container, corretto?

Sì, hai il tempo di inattività completo ogni volta che aggiorni postgresql (ogni anno o due, suppongo, più gli aggiornamenti di sicurezza a PostgreSQL stesso, anche se non sono stati così frequenti).

> [@rahim123](#):
>
> Vedo ancora pochissimo tempo di inattività con il meccanismo di aggiornamento della GUI.

Prima di cambiare, ho avuto un paio di fallimenti durante gli aggiornamenti della GUI, ma non ricordo più i dettagli; storia antica.

> [@rahim123](#):
>
> O devo anche accedere tramite SSH e ricompilare i container per applicare certi tipi di aggiornamenti di funzionalità/sicurezza?

Gli aggiornamenti della GUI non aggiornano l’immagine di base, quindi tutti gli aggiornamenti di sicurezza nel software fornito, come l’elaborazione delle immagini, non verranno applicati lì.

Mi piace ricompilare rapidamente il container dell’app come mia modalità **normale** per consumare gli aggiornamenti di sicurezza del container dell’app quando disponibili, in modo da non rimandare mai un tempo di inattività di 10 minuti per ricompilare tutto. Ecco perché `git pull` nel launcher fa parte della prima parte dell’applicazione di ogni aggiornamento; in modo che se l’immagine di base con cose come i programmi di elaborazione delle immagini è stata aggiornata, vengano applicati senza che io debba nemmeno pensare di chiedere se ci sono aggiornamenti di sicurezza da applicare. ☺

Ma alla fine, io _personalmente_ trovo l’approccio a due container più semplice per me, e **assolutamente** non sto cercando di convincere altre persone a farlo. Se non ti sembra più semplice in base alla tua conoscenza ed esperienza, **non** farlo solo perché la mia guida personale e opinabile lo identifica come utile in un certo contesto. 😁

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [12 Gennaio 2023, 5:23pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/18 "2023-01-12T17:23:43Z")

</div>

Capito! 😉 Anch’io tendo ad avere opinioni forti sui dettagli di implementazione tecnologica, ma apprezzo la tua prospettiva aggiuntiva.

> [@mcdanlj](#):
>
> Gli aggiornamenti della GUI non aggiornano l’immagine di base

> [@pfaffman](#):
>
> È almeno in gran parte vero che se c’è una nuova immagine di base, docker\_manager ti obbligherà a ottenerla (almeno, ci proverà).

Hmm, quindi è ancora così?

In ogni caso, nella mia esperienza con i forum tradizionali installati senza containerizzazione su uno stack LAMP/LEMP, il tipico vettore di vulnerabilità/attacco che porta a siti web compromessi nel mondo reale è quasi sempre nel codice dell’applicazione web o in uno dei suoi framework di sviluppo web. Quindi tendo ad avere un maggiore senso di urgenza verso gli aggiornamenti del codebase di Discourse, che sembrano essere gestiti dalla GUI, quindi immagino che mi stia orientando in quella direzione.

* * *

A proposito, in tema di downtime, una rapida menzione per Clear Linux: ho iniziato a testarlo a causa delle sue ottimizzazioni di basso livello nel puro calcolo numerico per cercare di risparmiare qualche ora sul mio enorme processo di importazione del forum. Potrebbero esserci effettivamente alcuni miglioramenti di velocità in quel caso, ma in generale, _santo cielo_, è _follemente veloce_ nel riavvio, specialmente come guest KVM. Sul livello più economico di VPS posso riavviare e accedere nuovamente via SSH in poco più di 5 secondi. Quindi non vedo l’ora di usarlo quando ci saranno importanti aggiornamenti del sistema operativo host.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [12 Gennaio 2023, 5:33pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/19 "2023-01-12T17:33:32Z")

</div>

> [@rahim123](#):
>
> Ma vedo ancora pochissimo tempo di inattività con il meccanismo di aggiornamento della GUI.

Sì. Ma un paio di volte all’anno devi eseguire una ricostruzione dalla riga di comando perché qualche componente nel container è stato aggiornato. E poi avrai 5-15 minuti di inattività. Eseguo quasi esclusivamente aggiornamenti dalla riga di comando (tranne sul mio dashboard dove potrei aggiornare solo il plugin del dashboard più volte al giorno) e ho un bel po’ di clienti per i quali eseguo quegli aggiornamenti dalla riga di comando quando sono richiesti (presumibilmente stanno eseguendo aggiornamenti tramite l’interfaccia web, ma spesso non lo fanno).

---

<div class="post-metadata">

### Author: ![rahim123](https://avatars.discourse-cdn.com/v4/letter/r/df705f/32.png) [@rahim123](https://meta.discourse.org/u/rahim123)
#### Post date: [12 Gennaio 2023, 5:35pm UTC](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355/20 "2023-01-12T17:35:30Z")

</div>

> [@pfaffman](#):
>
> Ma un paio di volte all’anno devi fare una ricostruzione dalla riga di comando perché qualche componente nel container è stato aggiornato

La dashboard di Discourse notifica specificamente questo tipo di aggiornamento richiesto? O dovrei tenere d’occhio le PSA di Debian?

[Pagina seguente](https://meta.discourse.org/t/mkjs-opinionated-discourse-deployment-configuration/193355.md?page=2)
