Soluzione alternativa per la pagina di manutenzione: è possibile farlo?

Sì, lo farei a fasi:

  1. procurati un server leggermente più potente
  2. fai funzionare l’installazione dei due contenitori

se a questo punto sei soddisfatto, fermati qui, oppure:

  1. implementa la pagina di manutenzione seguendo l’ottima guida di @Lilly sopra. :+1:

haha sono felice che tu l’abbia chiesto perché non ho preso il tempo di spiegare questa parte (avrei dovuto - c’è molto da spiegare e Cloudflare è complesso!)

quando la route degli workers è impostata, ogni singolo caricamento di immagine e visualizzazione di pagina sul forum viene instradato attraverso quell’worker.

Il piano CDN gratuito di Cloudflare include un limite di 100.000 richieste/giorno per una route degli workers.

quindi, se hai un forum relativamente trafficato, per evitare di raggiungere il limite del piano gratuito in un giorno, è una buona idea non tenerlo attivo tutto il tempo. Si tratta solo della route degli workers, non della pagina di manutenzione: puoi lasciare la pagina di manutenzione attiva tutto il tempo; non viene attivata a meno che tu non abbia abilitato la route degli workers. Si tratta semplicemente di questa parte del Passo 2 in cui hai assegnato la route (che è facile da impostare e rimuovere). A meno che tu non utilizzi un piano Cloudflare a pagamento, è quindi una buona pratica tenerla attiva solo quando esegui la tua manutenzione.

  1. vai alla pagina delle route degli workers di Cloudflare per il tuo dominio e clicca il pulsante sul lato destro della route.

  1. in basso nella schermata di modifica, clicca il pulsante remove per scollegare la pagina dell’worker dalla route.

  1. non preoccuparti, il codice dell’worker stesso non verrà eliminato, solo la regola di instradamento. La prossima volta che eseguirai una ricostruzione/aggiornamento, potrai semplicemente aggiungerlo di nuovo come nel Passo 2 sopra.

Se utilizzi un piano Cloudflare a pagamento, non devi preoccuparti di nulla. Tuttavia, in quel caso puoi utilizzare le pagine di errore di Cloudflare invece di una pagina degli workers… (ho già detto che Cloudflare è piuttosto complesso? LOL)

:warning: configurazione avanzata per amministratori di seguito

Se si desidera automatizzare completamente gli aggiornamenti con il piano gratuito, si dovrebbe utilizzare un token API di Cloudflare, il proprio zone-id e un comando curl per ottenere l’route id degli workers. Quindi modificare lo script /root/update-web.sh con qualche altra cosa divertente per attivare e disattivare automaticamente la route degli workers:

#!/bin/bash
cd /var/discourse

CF_TOKEN="your_actual_token_here" #<---token API di Cloudflare
ZONE_ID="xxxx" #<---dalla tua pagina profilo Cloudflare
ROUTE_ID="xxxx"
WORKER_NAME="my-site-maintenance-page"

echo "➡️ Pulling latest Discourse docker scripts..."
git pull

echo "➡️ Bootstrapping new web container in the background..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ Bootstrap successful!"
    
    # Turn ON the Cloudflare Maintenance Worker
    echo "🚧 Enabling Maintenance Page..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":"'$WORKER_NAME'"}' > /dev/null

    # Swap the containers (The 30-second downtime window)
    echo "🔄 Swapping containers..."
    ./launcher destroy web_only && ./launcher start web_only
    
    # Turn OFF the Cloudflare Maintenance Worker
    echo "🌍 Disabling Maintenance Page..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":null}' > /dev/null

    echo "🚀 Done! Site updated with zero visible downtime."
else
    echo "❌ Bootstrap failed! Aborting swap to keep current site online."
fi 

Utilizzo la versione precedente dello script perché non mi interessa automatizzare tutto e mi piace essere presente durante gli aggiornamenti/ricostruzioni. Aggiungo semplicemente la route degli workers subito prima di eseguire un aggiornamento e la rimuovo dopo. Ci vogliono solo pochi secondi.

I miei passaggi generali sono:

  1. aggiungere la route degli workers su Cloudflare
  2. accedere via SSH a Hetzner
  3. eseguire eventuali aggiornamenti di sistema (es: sudo apt update && sudo apt upgrade -y, quindi riavviare il server se necessario
  4. accedere di nuovo via SSH se è stato necessario riavviare
  5. eseguire ./update-web.sh
  6. rimuovere la route degli workers su Cloudflare

Non ho la minima idea di programmazione o del mondo dello sviluppo, oltre a quel semplice hello world che feci con Visual Basic tanto tempo fa. Però riesco a fare alcune cose, perché conosco meglio come amministrare i miei server WordPress e Mastodon/Pixelfed, e in qualche modo anche il mio Discourse. Poi c’è quella roba chiamata IA (che non è affatto facile per un principiante, come viene pubblicizzato).

Non so se sia anche solo remotamente possibile con Discourse a causa di Docker, ma nel mondo ordinario Nginx-Varnish-WordPress ho costruito un sistema in cui un server Plesk riceve informazioni sugli errori 50x e mostra una pagina di errore. In realtà ho tre configurazioni: il frontend Nginx mostra il contenuto di uno snapshot generato se Varnish è giù, Varnish inizia a usare lo snapshot per i contenuti non in cache quando il backend legato a WordPress è giù, e la terza è una pagina di errore se il frontend Nginx non risponde.

Le cose legate a Varnish non sono possibili per Discourse, ma non vedo alcun motivo per cui non si possa costruire una simile ragnatela anche nel mondo Docker, in cui qualsiasi errore 50x mostrerebbe una pagina di errore.

Potrebbe trattarsi di un sistema molto soggetto a errori. E non ho la più pallida idea di cosa succederebbe se ci fossero più di un pugno di utenti.

C’è anche la risposta più ovvia, ovviamente: usare ad esempio Nginx prima di Discourse. Lo usavo prima di passare alla configurazione a due container.

Alla fine ho trovato il tempo di reinstallare Discourse. Dopo aver valutato la mia situazione attuale e quanto manutenzione sembrino richiedere due container, credo che per il momento mi atterrò a uno solo; se in futuro avrò bisogno di due container, rivedrò tutto ciò che è stato detto qui. A parte l’installazione dei plugin, che non mi sembra qualcosa che dovrò fare così spesso come la gestione dei componenti, il fatto che la community sia offline per 20 minuti in un orario della giornata in cui ci sono meno utenti online, unito a un banner che avvisa gli utenti che la community sarà offline in un determinato giorno e orario, mi sembra piuttosto ragionevole per ora.

Vedremo come andrà.

Richiede quanto un singolo container :flushed_face:

E meno dolore :slight_smile:

Puoi chiarirmi come funziona?

Non sono sicuro se stavi rispondendo a me o a @Jagster? Cosa intendi?

Poiché il processo di avvio del nuovo contenitore, mantenendo il sito online, è molto meno stressante: se la build va in errore, non c’è bisogno di entrare nel panico e si ha tutto il tempo necessario per risolvere il problema senza dover andare offline.

Ok, quindi state incoraggiando ad averli entrambi, ecco perché si parla di “meno dolori”.
Quindi, in quanto persona non esperta in materia, avere 2 contenitori non significa avere due istanze di Discourse, credo?

Sto leggendo il topic

e

per capire quanto lavoro richiede e quanta attenzione serve, in modo da non ritrovarmi con qualcosa che non riesco a gestire, rendendo il processo più problematico di tutte le altre cose che possono andare storte con un solo contenitore.

Volevo solo elogiare la condivisione delle informazioni sulla configurazione con due contenitori. Ne stavo usando uno e di solito richiede da 3 a 5 minuti (su un server dedicato con 64 GB di RAM).

Potresti dirmi, con esempi chiari e semplici, quando si dovrebbe aggiornare entrambi i contenitori in un’installazione dual? Intendo dire: quali aggiornamenti di Discourse richiedono il riavvio di entrambi i contenitori e quali solo del web_container appena creato?

Innanzitutto segui delle istruzioni molto semplici su come avviare la configurazione a 2 contenitori. Dopo di che, nella maggior parte dei casi ti servirà solo

./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only ) 2>&1 | tee ~/$(date +%Y-%m-%d_%H-%M-%S)-upgrade.log'

La parte con tee serve solo per il logging, perché per me è più facile consultarlo rispetto al feed di tmux che utilizzo.

Ma in sostanza è esattamente la stessa cosa dell’uso di app.yml e della rebuild, solo che dà molto meno fastidio agli utenti. Certo, c’è il contenitore dati, ma richiede attenzione e cura molto raramente — e se farai qualche trucco più sofisticato con i contenitori, probabilmente sai già cosa fare e quando.

Se l’aggiornamento fallisce con la configurazione a 2 contenitori, hai comunque un forum attivo e funzionante, mentre con quello singolo andrebbe in crash.

Quindi, solo l’avvio iniziale è un po’ più impegnativo, ma le istruzioni sono piuttosto chiare. Direi che usare mail-reveiver è un compito più difficile, se si utilizza Amazon SES.

Ad esempio, questo è il tipo di commento che non posso semplicemente ignorare, perché sembra che aggiornare/aggiornare non sia più così semplice come cliccare su un pulsante, ma richieda più attenzione e concentrazione. Ciò che a una persona esperta può sembrare facile e ovvio, per qualcun altro che non lo è potrebbe non esserlo:

Diresti che le istruzioni in questa discussione sono ancora valide nel 2026, dato che risale al 2015?

Non mi dispiace provare, dato che ho appena reinstallato Discourse oggi. Se qualcosa andasse storto, posso sempre tornare a un singolo contenitore. Voglio solo essere sicuro che a metà del processo non faccia qualcosa che non è più corretto nel 2026…

Per me, risparmiare pochi minuti equivale a più di 20 minuti. È vero che è una volta al mese se si aggiorna una volta al mese, ma io eseguo gli aggiornamenti almeno due volte a settimana. E se un plugin fallisce e devo fare diversi tentativi (perché ovviamente lavoriamo con istanze live :wink:), quel lungo downtime diventa semplicemente doloroso.

Non ci sono dettagli negli annunci di ogni nuova release da seguire. Mcdanlj forse li ha, ma non è un sysadmin comune: lavora a un livello molto più alto.

Sono confuso…

Mentre tu dici:

la tua risposta qui sopra fa sembrare che ci sia più lavoro, quando dici:

Questo da solo fa sembrare che due container siano effettivamente più complessi da mantenere, non la stessa cosa di uno? Certo, il downtime e tutto il resto, lo capisco, ma la manutenzione dei container stessi sembra più complessa e più soggetta a errori rispetto a un semplice aggiornamento con un solo container. O sto sbagliando qualcosa?

Esatto:

Container 1 = sito web & nginx
Container 2 = database e redis

(Credo di aver capito bene)

Il contenuto del Container 1 cambia molto

Quello del Container 2 cambia molto raramente.

E puoi aggiornare il Container 1 senza dover aggiornare il Container 2.

E ancora meglio, puoi preparare un sostituto per il Container 1 e poi sostituirlo in pochi secondi (la preparazione si chiama “bootstrapping”)

Ti sfugge che, nel caso di un singolo container, il comando ./launcher rebuild app arresta sia la parte web che quella dei dati, esegue l’aggiornamento di entrambe, ma la sezione dati ne ha bisogno molto raramente, e dopo il completamento del processo tutto viene riavviato a condizione che non vi siano problemi.

Con due container, si ricostruisce solo la parte “web”, senza toccare il container dei dati; se tutto va liscio, verrà distrutto il vecchio container e avviato quello nuovo. Se invece qualcosa va storto, il tuo vecchio container “web”, ancora funzionante, resterà in uso.

Quindi, l’unica differenza sostanziale riguarda il modo in cui si gestisce il software e un paio di altre cose relative al database.

Certo, la configurazione con un singolo contenitore è un’opzione anche, naturalmente. Ma il punto principale è che quando si crea una configurazione a due contenitori, l’unica vera differenza nel nome del livello di difficoltà è il comando utilizzato durante l’aggiornamento — e per quello c’è alias :wink:

Quello era scritto nei tempi in cui le comunicazioni erano scritte a mano e dicevano qualcosa sul fatto che fosse il momento di aggiornare il database. Il nuovo sito automatizzato è più appariscente, ma non c’è più la nota umana su cosa sia in realtà più importante, come c’era un tempo.

Oggi, immagino, devi accorgerti di un post che il database sta ricevendo un aggiornamento? Sembra che io li abbia persi per mesi.

Tuttavia, questo accade una volta ogni pochi anni, e viene ricostruito quando si ricostruisce esplicitamente il DB, e CDCK sembra aver mantenuto la compatibilità con le versioni più vecchie di pgsql per un po’. Quindi non mi ha mai davvero creato problemi. Finora.

Mi piace davvero la configurazione a due contenitori (o più!) per me stesso, ma la consiglio comunque con cautela perché non è la più semplice per tutti. È difficile per me giudicare per chi la distribuzione a due contenitori sembrerà “ovviamente, è semplice” e per chi sarà “ahia, voglio solo premere un pulsante”.