Ho gestito un forum Discourse con una quantità sostanziale di contenuti e molte immagini negli ultimi anni. Maker Forums 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 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. (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:
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.)
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.
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 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.
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:
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 (che Discourse fa), e permetto anche l’overcommit della memoria.
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 è 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.
./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.
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.
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:
(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:
Se hai 4 GB o più di memoria, o più CPU, leggi i consigli a:
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:
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 che una volta all’anno, genererà un post come 2020: The Year in Review e alla fine lo invierà via email ai tuoi utenti inattivi che potrebbe incoraggiarli a rinnovare la partecipazione.
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.
Assicurati di avere SPF 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.
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 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.
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:
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.
# systemctl edit certbot-renew
Per un sistema senza un ricevitore di posta, ho aggiunto le due righe:
[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:
[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:
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.
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:
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.
...
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:
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:
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:
Non affrettarti con gli upload S3
Sii molto sicuro che vuoi sempre usare S3 (o equivalente) per le immagini caricate 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:
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; e che in questo momento, finché non usi “Rocket Loader” funziona correttamente.
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.
La funzione 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 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 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. 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.
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.
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.
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:
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. Ecco una ricetta di esempio.
# 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.
# 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.
# 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.
# 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 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 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.
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:
# 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
[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.
# 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
- 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 per trasmettere backup Postgres quasi istantanei con minio-client utilizzando il comando archive-command in postgresql, simile ai backup upload streaming.
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).
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:
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(oapt install sysstatsu debian e derivati)systemctl enable --now sysstatsystemctl enable --now sysstat-collect.timersystemctl enable --now sysstat-summary.timersystemctl edit sysstat-collect.timere cambiaOnCalendar=*:00/10inOnCalendar=*:00/2- Se /etc/default/sysstat esiste, cambia
falseintrue
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.