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 gestire entrambi i pezzi rotti. Se leggi le istruzioni qui sotto e ti sembrano magia, invece di chiarire come funzionano realmente le cose all’interno dei container, scappa, non camminare, verso il tuo deployment autonomo predefinito più vicino: farai un favore a te stesso.
Il metodo raccomandato per migrare da un deployment a singolo container a un deployment multi-container è essenzialmente:
- Esegui un backup del tuo Discourse
- Butta via tutto
- Ricomincia da zero con un deployment multi-container
- Ripristina il tuo backup
Se, come me, hai un sito grande che richiede ore per il ripristino, potresti chiederti se esista un modo più veloce. Non chiedertelo più! Ho migrato da un deployment autonomo a un deployment a tre container (web, data e redis) in meno tempo di quanto impieghi solitamente a eseguire ./launcher rebuild app per quel sito. (12 minuti di downtime totale, quando il rebuild dell’app ha talvolta richiesto oltre 30 minuti.) Basandomi sulla mia esperienza, in futuro terrei Redis insieme a Postgres in un singolo container data.
Se fai questo, assumiti la responsabilità di sapere quando è necessario ricostruire gli altri container (data e, se sei sciocco come me e separi Redis, anche Redis). Non riceverai più aggiornamenti gratuiti di tutto con ./launcher rebuild app — se non hai le risorse per gestire questo processo, usa un deployment autonomo o acquista Discourse ospitato.
Test
Non usare questo processo per migrare verso più container a meno che, dopo averlo letto, tu non capisca anche come si potrebbe migrare rapidamente da più container a un singolo container. Se questo non ti è ovvio dopo aver letto questo post, allora questo articolo rappresenta una tecnologia sufficientemente avanzata (cioè indistinguibile dalla magia), ed è possibile che tu non riesca nemmeno a riconoscere se questo processo si interrompe a metà strada, rischiando di ritrovarti con un Discourse rotto che non riconosci fino a molto dopo. Se ciò accade, dovrai tenere entrambi i pezzi rotti. Se lo rompi, te lo compri, come si dice!
Backup
Esegui prima il backup e attiva subito i backup delle miniature, così da non doverle ricostruire tutte durante il ripristino. Se commetti un errore qui, potresti facilmente trovarti in una situazione in cui il modo più semplice, sicuro e veloce per recuperare è tornare al metodo normale. Sii pronto a ripiegare sul metodo raccomandato se qualcosa va storto.
Scarica il tuo backup. I comandi qui sotto comportano lo spostamento di file all’interno dei dati di Discourse; se commetti un errore, potresti aver cancellato il tuo backup. Quindi, scaricalo. Inoltre, se il tuo backup non include gli upload, fanne un backup anche di quelli. Si trovano anch’essi nella posizione dove sposterai i file.
Davvero, fai un backup.
Quando ho fatto questo, prima ho eseguito un backup, poi un backup remoto del sistema, prima di procedere oltre.
Configurazione del nuovo deployment multi-container
Avrai bisogno almeno di containers/web_only.yml e containers/data.yml, e se vuoi anche separare Redis, anche di containers/redis.yml. Inizia copiando samples/data.yml (e opzionalmente samples/redis.yml) nella directory containers/.
Se stai distribuendo Redis separatamente, rimuovi il template di Redis dalla parte superiore del file containers/data.yml. (Ma non farlo senza una buona ragione; è solo lavoro extra.)
Hai due modi per creare web_only.yml.
- Copia
samples/web_only.ymlincontainers/; poi confronta entrambi concontainers/app.yml, preservando qualsiasi configurazione di postgres inparams:nel tuo nuovocontainers/data.yml
- Copia qualsiasi
params:per postgres dacontainers/app.ymlincontainers/data.yml - Crea una password univoca da sostituire a
SOME_SECRET
- In alternativa, copia
containers/app.ymlincontainers/web_only.ymle confrontalo consamples/web_only.yml,
- Rimuovi tutti i riferimenti ai template di postgres e redis
- Rimuovi l’intera sezione
params:che conteneva solo impostazioni di postgres - Aggiungi una sezione
links:fedele asamples/web_only.ymlo modificata (vedi sotto) se stai distribuendo Redis in un container separato - Aggiungi una sezione database da
samples/web_only.ymle crea una password univoca da sostituire aSOME_SECRET - Cambia le definizioni dei volumi da
standaloneaweb_only
Ecco la sezione links: da usare se stai separando Redis nel suo container invece di usare la ragionevole opzione predefinita di raggrupparlo con postgres nel container data:
# Usa la chiave 'links' per collegare i container insieme, ovvero usa il flag Docker --link.
links:
- link:
name: data
alias: data
- link:
name: redis
alias: redis
Il link redis non è necessario se stai combinando i container redis e postgres in un unico container data; questo serve solo a mostrare cosa faresti.
Ecco una copia delle attuali impostazioni postgres in env in samples/data.yml che dovrai modificare sostituendo SOME_SECRET:
## TODO: configura la connettività ai database
DISCOURSE_DB_SOCKET: ''
#DISCOURSE_DB_USERNAME: discourse
DISCOURSE_DB_PASSWORD: SOME_SECRET
DISCOURSE_DB_HOST: data
## Se usi un unico container data+redis, il seguente sarà "data"
DISCOURSE_REDIS_HOST: redis
Nota che per un deployment normale (non multisito) non dovrai modificare altre righe. DISCOURSE_DB_SOCKET è per un socket di dominio Unix per Postgres, non è un numero di porta.
Ecco un esempio della modifica alla definizione dei volumi alla fine di web_only.yml che dovrai usare se lo copi da app.yml invece che da samples/web_only.yml:
@@ -75,10 +80,10 @@
## Il container Docker è senza stato; tutti i dati sono archiviati in /shared
volumes:
- volume:
- host: /var/discourse/shared/standalone
+ host: /var/discourse/shared/web_only
guest: /shared
- volume:
- host: /var/discourse/shared/standalone/log/var-log
+ host: /var/discourse/shared/web_only/log/var-log
guest: /var/log
Ora imposta la stessa password segreta usata in containers/web_only.yml in containers/data.yml al posto di SOME_SECRET.
Ora sei pronto per la migrazione.
Ora è il momento di eseguire e scaricare il tuo ultimo backup prima di provare la migrazione veloce. Ricorda, se qualcosa va storto qui, passa immediatamente al metodo raccomandato. Non posso sottolinearlo abbastanza.
Container data (postgres) e redis separati:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mkdir redis
mv standalone/postgres_* data/
mv standalone/redis_data/ redis/
mv standalone web_only
mkdir -p data/log/var-log
mkdir -p redis/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher bootstrap redis
./launcher start redis
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
Container data combinato postgres+redis:
cd /var/discourse
./launcher stop app
cd shared
mkdir data
mv standalone/postgres_* data/
mv standalone/redis_data/ data/
mv standalone web_only
mkdir -p data/log/var-log
cd ..
./launcher destroy app
./launcher bootstrap data
./launcher start data
./launcher bootstrap web_only
./launcher start web_only
Nota anche che se hai precedentemente configurato nginx esterno, dovrai cambiare il percorso proxy_pass per corrispondere alla nuova posizione del socket web_only; ad esempio da http://unix:/var/discourse/shared/standalone/nginx.http.sock: a http://unix:/var/discourse/shared/web_only/nginx.http.sock:
Per me, su una VM a 2 core con 4 GB di RAM e un sito con backup da 600 MB senza download, questo processo ha comportato 12 minuti di downtime. I risultati possono variare.
Nota che finora nulla di questo aggiorna il launcher. Potresti non essere aggiornato. (Ad esempio, ho eseguito questo dopo che era disponibile l’aggiornamento a postgres 12, ma prima di averlo applicato. Questo processo mi ha lasciato con postgres 10. Poi la cosa successiva che ho fatto è stata ricostruire l’app data, che ha aggiornato il launcher e mi ha portato con successo attraverso il processo di aggiornamento a postgres 12.)
Cosa fare per gli aggiornamenti futuri
Dopo questa migrazione, se hai bisogno di aggiornare Redis o data, devi prima fermare l’app web. Questo assomiglierebbe a qualcosa del genere:
./launcher stop web_only
./launcher rebuild data # e/o redis
./launcher rebuild web_only
Nota che se ricostruisci il container data (o postgres, o redis), dovrai creare un nuovo container web per ricollegarlo al nuovo container data. Puoi farlo ricostruendo web_only o, se non pensi di doverlo ricostruire, un ./launcher destroy web_only; ./launcher start web_only farà al caso tuo (e se ricevi un errore su „container data mancante“ o simile, è questo che devi fare).
Tuttavia, quando né postgres né redis necessitano di un aggiornamento, è molto più veloce non dover ricostruire quei container, e la maggior parte dei rebuild dell’app sono semplicemente ./launcher rebuild web_only.
In alternativa, per un downtime ancora minore (variamente riportato tra 15 secondi e 2 minuti):
./launcher bootstrap web_only
./launcher destroy web_only && ./launcher start web_only
Ancora una volta, passando a un deployment multi-container, tenere traccia di quando ciò è appropriato è ora il tuo lavoro. Riceverai notifiche nella console di Amministratore riguardo agli aggiornamenti, ma si applicheranno solo al container web_only. Nulla ti dirà quando devi aggiornare postgres o redis. Se fai questo, leggi la categoria Annunci prima di ogni aggiornamento di versione che effettui, e leggi le note di rilascio per ogni nuova versione a cui stai aggiornando o attraverso cui passi. Cioè, se salti un aggiornamento di versione, non saltare la lettura delle note di rilascio per la versione che hai saltato. (Considera di impostare un monitoraggio sulle note di rilascio o di iscrivere il tuo lettore feed a https://meta.discourse.org/tag/release-notes.rss per rimanere aggiornato.)
Nota che ricostruire il container web_only richiede che il database sia in esecuzione, quindi non puoi velocizzare le cose ricostruendo in parallelo tutti e due o tre i container. Se hai intenzione di ricostruirli tutti ogni volta, attieniti al deployment autonomo standard raccomandato; sarà più veloce che gestire più container.
Revisione del backup
Se fai il backup degli upload separatamente dal database, spero tu abbia un regime di backup remoto basato su file per gli upload in modo che vengano salvati per il ripristino in caso di disastro.
Rivedi la tua implementazione del backup remoto per assicurarti che faccia il backup degli upload in /var/discourse/shared/web_only invece che in /var/discourse/shared/standalone, in modo da mantenere i tuoi backup aggiornati nella tua nuova implementazione multi-container.