Configurazione di distribuzione di Discourse secondo l'opinione di MKJ

Michael,

Ora che l’ho usato, sono d’accordo sul fatto che restic sia “il migliore” per i backup, ma sono curioso di sapere se, alla luce della recente controversia su Minio, tu abbia utilizzato un’alternativa compatibile come Garage al suo posto. O la risposta è “non importa, usano tutti gli stessi comandi, quindi puoi usare quello che preferisci”? Sono strumenti che sto imparando solo ora, quindi non conosco le differenze dettagliate, so solo che le indicazioni attuali consigliano di usare Garage invece di Minio.

1 Mi Piace

Oh, sì, sono sicuro che oggi inizierei nel mio garage. È solo che non ho ancora migrato.

1 Mi Piace

Grazie anche a @raykholo per avermi segnalato fuori banda che le mie istruzioni per disabilitare le huge pages trasparenti erano silenziosamente errate.

Chi segue questa questione, usate invece questo:

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

Questi non sono configurabili tramite sysctl e, se avete precedentemente creato /etc/sysctl.d/10-huge-pages.conf seguendo le mie istruzioni precedenti, potete eliminarlo.

Non ho convalidato correttamente quando l’ho scritto e non ho notato da allora che non funzionava correttamente. Buona osservazione, grazie!

3 Mi Piace

Mmh. Ho due sistemi e li ho appena esaminati, e potrei ipotizzare che per Ubuntu 22 tu abbia ragione e che la tua correzione sia stata utile, ma per Ubuntu 24 non è necessaria. Scrivendo questo, mi rendo conto che la tua correzione potrebbe essere efficace anche in Ubuntu 24, anche se non è necessaria. Con quale versione del sistema operativo stai lavorando?

Si tratta di una questione di configurazione predefinita. È sicuro disabilitarla se è già disabilitata (nessun effetto) e il metodo ora descritto è ampiamente supportato.

Sto utilizzando AlmaLinux, come descritto in cima. Una volta che Docker ha finalmente aggiunto il supporto per gli spazi dei nomi v2, ho colto la prima opportunità per passare a un sistema operativo derivato da Red Hat.

1 Mi Piace

Forse rispondendo alla mia stessa domanda, ecco alcune note derivanti dal tentativo di utilizzare Garage con la tua guida operativa:


1. Garage non supporta i “tag di autorizzazione” sui file (questa è la vera lacuna di Garage)

Amazon ti permette di contrassegnare ogni file come “pubblico” o “privato” individualmente. Garage non implementa questa funzionalità.

Discourse cerca di usarlo di default. L’aspetto subdolo: quando Discourse diceva “salva questo file, contrassegnalo come pubblico”, Garage accettava la richiesta e ignorava silenziosamente il tag. Quindi i caricamenti base sembravano funzionare correttamente, e si sarebbe rotto solo molto più tardi, la prima volta che qualcuno avesse reso un caricamento privato.

Soluzione: dire a Discourse di smettere di usare i tag (un’impostazione). Cloudflare R2 ha la stessa lacuna e riceve la stessa soluzione. Garage gestisce le autorizzazioni in modo autonomo, a livello di bucket, che è tutto ciò di cui abbiamo bisogno.


2. Discourse insiste nel nominare i bucket in un modo specifico (non è un difetto di Garage)

Discourse non dirà “il server su garage, bucket uploads”. Insiste su uploads.garage — il nome del bucket incollato all’inizio, come un sottodominio. E non c’è alcuna opzione per disabilitarlo.

Nessuna parte della nostra rete conosceva quel nome, quindi Discourse non poteva connettersi affatto — l’installazione è fallita a metà.

Soluzione: ho dato a Garage quello stile di denominazione e ho registrato i nomi. Due righe di configurazione.

Questa è una peculiarità nota di Discourse, non di Garage — è il motivo per cui lo storage di Oracle è nella lista ufficiale “non funzionante” di Discourse.


3. Le immagini avevano bisogno di un indirizzo web pubblico (nulla a che fare con Garage)

Discourse scrive l’indirizzo di ogni immagine nel post in modo permanente. Senza dirgli l’indirizzo pubblico in anticipo, ha salvato indirizzi interni raggiungibili solo dal nostro server — quindi ogni immagine sarebbe risultata rotta per i visitatori, per sempre, a meno che non ricostruissimo ogni post.

Soluzione: impostare l’indirizzo CDN prima del primo caricamento. Sarebbe stato identico su Amazon, R2, qualsiasi altro servizio.


Nota: ognuno di questi problemi è stato silenzioso. Nulla ha detto “non supportato”. Uno ha accettato la richiesta e l’ha ignorata, uno sembrava un errore di rete, uno sembrava funzionare perfettamente.

Quindi, solo alcune cose iniziali da tenere a mente per un nuovo utente che prova questo per la prima volta, e/o per qualcuno che cerca di seguire la guida operativa di Michael con Garage.

Ecco le note AI complete su ciò che abbiamo sperimentato ora che il forum è stato distribuito:


Esecuzione di Discourse su Garage self-hosted (S3) dietro un tunnel Cloudflare — note

Garage non è presente nella tabella di compatibilità “Configurare un provider di storage oggetti compatibile con S3”, quindi ecco un dato. Configurazione: Garage v2.3.0, Discourse in due container, Debian 13,
nodo singolo, tunnel Cloudflare invece di un nginx esterno. Premessa: questa è una
piccola distribuzione senza traffico di produzione, quindi trattatela come “funziona” e non come “testata
alla scala di Maker Forums”.

  1. Funziona. Verificato contro i percorsi di codice di Discourse, non tramite CLI: UploadCreator,
    OptimizedImage, ListObjectsV2, HeadObject/GetObject con round trip byte-esatto,
    multipart, delete, remove_upload, più BackupRestore::Backuper che scrive nel bucket
    dei backup e BackupStore#files / #download_file che lo legge. La configurazione del ciclo di vita
    funziona, quindi s3_configure_tombstone_policy ha effettivamente effetto invece di essere
    ignorata silenziosamente. PutBucketCors funziona, quindi CORS manuale va bene.

  2. Devi configurare l’indirizzamento in stile virtual-host, e romperà db:migrate se non lo fai.
    Discourse trasforma l’endpoint http://garage:3900 + bucket “uploads” nell’host
    uploads.garage:3900, e non c’è alcuna opzione path-style in s3_helper.rb o
    site_settings.yml. Sono richieste due parti: root_domain sotto [s3_api] in garage.toml,
    E un nome DNS risolvibile per bucket (un alias di rete Docker per bucket, poiché il DNS
    Docker non ha wildcard). Il sintomo se lo perdi è un errore Aws::Waiters su
    getaddrinfo durante SiteIconManager.ensure_optimized! — sembra un guasto di rete, non
    di storage. Ogni nuovo bucket ha bisogno di un nuovo nome.

  3. Garage non implementa PutObjectAcl / GetObjectAcl, quindi imposta s3_use_acls su false —
    come R2. Due trappole qui. Prima, PutObject con --acl public-read è
    ACCETTATO silenziosamente e l’header è ignorato, quindi i test di caricamento base passano e si rompe solo più tardi
    su una transizione a upload sicuro. Seconda, DISCOURSE_S3_USE_ACLS non è una variabile globale nascosta —
    metterla in app.yml non fa nulla. È risultata true al mio primo avvio nonostante fosse
    nell’ambiente. Deve essere un’impostazione di sito, e deve essere ricontrollata dopo ogni rebuild
    perché nulla ti avvisa.

  4. Se metti un CDN davanti, puntalo all’endpoint WEB di Garage (:3902), non all’API S3
    (:3900). Le letture anonime funzionano solo sull’endpoint web; l’API S3 restituisce correttamente 403
    alle richieste non autenticate, quindi un CDN puntato a :3900 fallisce su ogni immagine mentre le tue
    credenziali sono perfettamente valide. Hai anche bisogno di garage bucket website --allow sul
    bucket uploads, e di un root_domain sotto [s3_web]. Attivalo solo su uploads — il
    bucket dei backup non deve mai essere leggibile anonimamente.

  5. ListObjectVersions restituisce NotImplemented su Garage. Non importa: cercando
    s3_helper.rb e file_store/s3_store.rb per list_object_versions / object_versions
    non si trovano occorrenze. Discourse non usa la versioning degli oggetti S3; la scadenza dei tombstone è
    tramite regole di ciclo di vita più un prefisso.

  6. Testare con aws-cli o mc NON prova la compatibilità. Entrambi usano di default
    l’indirizzamento path-style contro un endpoint personalizzato; Discourse usa solo virtual-host style. Il mio passaggio
    CLI è tornato 15/16 e sembrava un via libera, poi l’installazione reale è fallita
    immediatamente sulla differenza di indirizzamento. Stesso storage, stesse credenziali, stesse
    operazioni. Se stai valutando un backend S3 non provato, fai girare un vero Discourse — una
    istanza single-container usa e getta è sufficiente, e farlo prima che esista contenuto è il punto, poiché S3 → locale è a senso unico.

  7. Specificamente su un tunnel Cloudflare: la sezione external-nginx-for-SSL non si applica
    (TLS termina al bordo, nessun certbot, nessuna porta 80/443 in ingresso), ma la configurazione real-IP outlet
    è ancora essenziale e forse più importante. Usa real_ip_header CF-Connecting-IP
    invece di X-Forwarded-For — quando il tunnel è l’unico percorso di ingresso è un singolo
    valore edge-set inequivocabile. Verificalo pubblicando da un IP pubblico noto e controllando
    cosa ha registrato nginx; senza di esso Discourse registra l’indirizzo Docker del connettore per
    ogni richiesta e limita la velocità di tutto l’Internet come un solo cliente. Ciò che perdi rispetto
    all’approccio external-nginx è la pagina di manutenzione durante i rebuild — cloudflared
    non può servirla.

  8. Minore correzione a qualcosa ampiamente (male)detto, incluso da me: DISCOURSE_S3_CDN_URL
    non è incorporato in modo irreversibile negli URL memorizzati. upload.url memorizza l’URL S3 grezzo con
    l’host interno, ma Discourse sostituisce l’host CDN al momento del rendering tramite
    Discourse.store.cdn_url / UrlHelper.cook_url. Impostarlo in ritardo è recuperabile — il
    costo è rake posts:rebake, perché posts.cooked memorizza in cache l’HTML dal momento della cottura. Impostalo comunque
    prima del primo caricamento; ma non andare nel panico se non l’hai fatto.

  9. Due note operative non correlate a Garage. ./launcher eco la riga docker run completa
    inclusa DISCOURSE_S3_SECRET_ACCESS_KEY in testo piano, quindi i log di bootstrap contengono segreti — vale la pena ruotare le chiavi dopo un’installazione rumorosa. E un Garage single-node
    richiede comunque layout assign + layout apply prima di memorizzare qualcosa, con
    replication_factor = 1 che significa nessuna replica, quindi il tuo lavoro di backup è l’unica
    durabilità che hai.

Non utilizzo un object store per l’accesso pubblico in Discourse, in parte perché la migrazione è a senso unico e anche perché non ne ho bisogno; nel mio caso, significherebbe servire quei dati dallo stesso storage, solo con un’altra VM da gestire. Utilizzo un object store solo come destinazione per i backup con restic, eseguiti al di fuori di Discourse.

I backup di Discourse con miniature ma senza immagini, combinati con i backup a livello di host delle cartelle uploads, eseguiti con restic sull’host, significano che quelle limitazioni sono, per quanto ne so, irrilevanti.