Ich versuche, ein CDN für mein Forum einzurichten. Da China Fastly und viele CDN-Server verboten hat, kann ich diese nicht nutzen, um mein Forum zu beschleunigen. Nach einiger Recherche habe ich mich für Jsdelivr entschieden, das statische Dateien aus npm oder einem GitHub-Repository bereitstellen kann.
Ich weiß, dass ich in der app.yml die Variable DISCOURSE_CDN_URL verwenden kann, um die URL einzurichten. Doch bevor ich das tue, muss ich alle statischen Dateien (JS, CSS) aus meinem Forum sammeln und auf GitHub hochladen, damit Jsdelivr darauf zugreifen kann. Ich habe festgestellt, dass sich die statischen Dateien tatsächlich im Docker-Container befinden:
/var/www/discourse/app/assets
Ich überlege also, jedes Mal nach einem Neuaufbau der App alle Dateien aus diesem Pfad zu kopieren und auf GitHub hochzuladen. Diese Idee sollte funktionieren, aber die eigentlichen Anfragen enthalten lange Hash-Namen, von denen ich nicht weiß, wie man sie erhält. Zum Beispiel wird aus
Es handelt sich um einen SHA1-Hash des Dateiinhalts. Er wird hier generiert:
Die kompilierten Versionen, die verwendet werden, landen in /var/www/discourse/public/assets/.
Wenn du einen Abschnitt zu deiner app.yml hinzufügst, kannst du eine Aktion ausführen, nachdem der Container neu erstellt wurde. Zum Beispiel verwenden wir für das Hochladen nach S3 etwas Ähnliches wie:
In deinem Fall ersetze die Rake-Aufgabe durch die Befehle, die du ausführst, um die kompilierten Assets nach dem Build des Containers zu Github zu pushen.
Vielen Dank, @schleifer. Deine Antwort war sehr hilfreich. Allerdings habe ich noch ein paar Nachfragen:
Wo finde ich die Dokumentation für Hooks wie after_assets_precompile? Ich habe sowohl die Docker-Dokumentation als auch das Discourse-GitHub-Repository durchsucht, konnte aber keine Informationen dazu finden. Muss ich die Hooks mit dem Namen after_assets_precompile selbst einrichten (und wenn ja, wie?), oder sind sie bereits wie after_code von Discourse konfiguriert?
Wie ich es verstehe, würde mein Pseudocode so aussehen:
hooks:
after_assets_precompile:
- exec:
cd: $home
cmd:
- in den Docker-Container wechseln
- cd in `/var/www/discourse/public/assets/`
- git add, commit und Push zum GitHub-Repo durchführen
Das ist eine gute Frage, aber ich habe keine gute Antwort dafür.
Das im Container verwendete Konfigurationssystem ist:
Das README dort beschreibt allgemein, wie Hooks funktionieren. Die spezifisch verfügbaren Hooks hängen davon ab, wie Ihre Instanz eingerichtet ist – die Hauptdatei app.yml enthält eine oder mehrere Vorlagen. In den meisten Fällen ist eine davon web.template.yml:
Dort ist der Hook assets_precompile definiert (zum Zeitpunkt dieses Schreibens auf Zeile 159). Gemäß der Pups-Dokumentation können Sie mit before_assets_precompile bzw. after_assets_precompile andere Befehle vor oder nach dem Abschluss ausführen.
Die Befehle werden innerhalb des Docker-Containers ausgeführt, sodass Sie dafür nichts weiter tun müssen.
Die Direktive cd: kann direkt auf /var/www/discourse/public/assets/ zeigen, und jede Zeile in cmd wird aus diesem Verzeichnis ausgeführt. (Warnung: Jede Zeile in einem cmd-Array wird in einer separaten Shell ausgeführt, ähnlich wie in einer Makefile).
Ich bin mir nicht sicher, ob der Inhalt von /var/www/discourse/public/assets/ zwischen den Builds erhalten bleibt. Möglicherweise müssen Sie daher jedes Mal ein lokales Git-Repository erstellen und einen Force-Push durchführen. Die „korrektere“ Lösung könnte darin bestehen, in app.yml ein Docker-Volume für das Assets-Verzeichnis zu definieren, das auf einem in app.yml definierten Docker-Volume basiert wie die anderen und außerhalb des Containers persistent bleibt.
Vielen Dank. Ich habe auch festgestellt, dass einige statische Assets (wie CSS) in /var/www/discourse/tmp/stylesheet-cache abgelegt werden. Es gibt jedoch noch zwei weitere Probleme:
Benutzer-Uploads wie Avatare werden nach der Einrichtung von DISCOURSE_CDN_URL ebenfalls über das CDN bereitgestellt. Allerdings scheint es keine gute Lösung zu sein, hochgeladene Assets nach jedem Upload erneut auf GitHub zu pushen.
Wenn Discourse nach einem Benutzer-Avatar wie 2_2.png fragt, führt es folgende Schritte aus: 1) Es wird der Dateiname aufgeteilt, 2) einige Prüfungen durchgeführt, 3) und der tatsächliche Dateiname mittels Hashing berechnet. Wenn ich Benutzer-Avatare bereitstellen möchte, muss ich diese Logik selbst implementieren, da es keine Datei namens 2_2.png gibt.
Meine endgültige Lösung ist einfach: 1) Ich schalte Nginx vor mein Forum, wie in diesem Beitrag beschrieben. 2) Ich sammle alle statischen Assets aus dem oben genannten Pfad und pushe sie auf GitHub. 3) In der Nginx-Konfigurationsdatei füge ich folgende Regeln hinzu: