Sichern Sie Ihre Site mit git und Makefile

Durch die Übersetzung einer Site in eine Reihe statischer Webseiten können Sie die Belastung des Servers verringern oder sogar den freien Speicherplatz nutzen sowie die Zuverlässigkeit, Geschwindigkeit und Sicherheit der Site erhöhen. In diesem Artikel werde ich darüber sprechen, wie dies mit den bekannten Git- und Makefile- Tools gemacht wird. Ein Plus dieses Ansatzes ist die Möglichkeit, Versionen von Webseiteninhalten zu steuern.


In diesem Artikel wird beschrieben, wie statische Versionen von Webseiten für die Serverausgabe erstellt und zur Versionskontrolle und Sicherung in ein Repository gestellt werden. Gleichzeitig können statische und Mediendateien getrennt gespeichert und auf andere Weise archiviert werden (statische Dateien werden normalerweise im Repository für den Programmcode der Site abgelegt). Die Methode funktioniert auch für Seiten mit Unicode-Namen (z. B. für kyrillische Domänen). Am Ende steht ein funktionierendes Makefile.


Der Autor verwendet den Stapel django / uwsgi / nginx, einen virtuellen dedizierten Server unter GNU / Linux. Der Inhalt des Artikels ist jedoch nahezu unabhängig von bestimmten Technologien.


Seiten laden


Wir werden die Seiten der Site mit dem Standard- Wget- Programm speichern. Wir speichern jede Site in einem separaten Verzeichnis (das möglicherweise nicht mit dem Domainnamen der Site verknüpft ist).


Innerhalb jedes Verzeichnisses werden Seiten rekursiv mit der Taste wget -r gespeichert (es wird davon ausgegangen, dass auf alle Seiten über Links von der Hauptseite aus zugegriffen werden kann). Standardmäßig geht das rekursive Kopieren auf Stufe 5, dies kann jedoch mit der Option -l geändert werden.


Wenn wir Medien und statische Dateien getrennt von Textseiten speichern, werden die entsprechenden Verzeichnisse mit dem Schalter -X ignoriert.


Der vollständige Befehl sieht folgendermaßen aus:


mkdir primer cd primer wget -r -nH -X ,static --restrict-file-names=nocontrol . 

-nH bedeutet --no-Host-Verzeichnisse . Standardmäßig legt wget -r example.com alles im Verzeichnis example.com/ ab. Mit dieser Option wird die Erstellung des Verzeichnisses mit dem Hostnamen abgebrochen.


Die Option --restrict-file-names gibt an, dass beim Erstellen lokaler Dateien Zeichen in der URL maskiert werden. Ein Wert von nocontrol bedeutet, dass das Escapezeichen deaktiviert wird, und ist sehr wichtig für das Speichern von Seiten mit kyrillischen Links. Ohne sie werden die Seiten in Dateien mit leicht geänderten Namen gespeichert, und es ist nicht ganz klar, wie sie an den Server ausgegeben werden sollen. Leider funktioniert --restrict-file-names = nocontrol für Windows-Benutzer nicht. Dies ist ein bekanntes Problem .


Zum Git hinzufügen


Mit dem Befehl git init wird ein neues Repository erstellt. Standardmäßig wird es im aktuellen Verzeichnis im Ordner .git erstellt. Wir möchten jedoch, dass der Server nur auf die Dateien zugreifen kann, die den Namen der geöffneten Seiten der Site entsprechen. Daher sieht der vollständige Befehl, der ein sauberes (nacktes) Repository im Ordner ../.git-primer erstellt, folgendermaßen aus:


 git init --bare ../.git-primer 

Um dieses nicht standardmäßige Repository weiter zu verwenden, müssen Sie git die Optionen git-dir und work-tree übergeben :


 git --git-dir=../.git-primer --work-tree=. add . 

Makefile schreiben


Beginnen wir mit der Ankündigung unserer Projekte:


 SITES := example primer all : $(SITES) .PHONY : $(SITES) 

Die Variable SITES enthält die Namen unserer Projekte. Das Standardziel ist das erste Ziel, dh um alle Schritte auszuführen, geben Sie einfach einen Befehl make ein . Alle Ziele in SITES sind fiktiv ( PHONY ): Das Rezept für jedes dieser Ziele wird unabhängig von der Existenz des Verzeichnisses und dem Zeitpunkt seiner Änderung ausgeführt.
Die grundlegende Einführung zu machen kann zum Beispiel hier gelesen werden , und die grundlegende Anleitung ist info make ( Original , Übersetzung ).


Die Regel für jedes der Projekte sieht folgendermaßen aus:


 $(SITES) : if [[ -d .git-$@ ]]; \ then \ $(get-data); \ $(mgit) add . && \ if [[ -n "`$(mgit) status --porcelain`" ]]; then \ $(mgit) commit -m "Update $@."; \ fi \ else \ $(init-git); \ fi 

Diese Regel ist im Wesentlichen ein einzelner Shell-Befehl.
$ @ Ist eine automatische Variable , die den Namen des aktuellen Ziels enthält (z. B. Primer).
Zuerst prüfen wir, ob das .git-primer-Verzeichnis existiert. Wenn ja, gehen Sie zum Projektverzeichnis, laden Sie die Seiten herunter und fügen Sie sie zu git hinzu.
Wenn sich der Inhalt der Seiten nicht geändert hat, fügt git nichts hinzu. In diesem Fall führt Commit jedoch zu einem Fehler und die Ausführung des Makefiles wird gestoppt. Daher rufen wir zuerst den Git-Status mit der Option Porzellan auf , die für die Verwendung in Skripten vorgesehen ist. Wenn die Länge der Ausgabezeile von git status --porcelain nicht Null ist, können wir ( von hier aus ) ein Commit durchführen.


get-data, mgit und init-git sind vorgefertigte Rezepte im Makefile. Beispielsweise ist mgit ein Git- Aufruf, der ein Verzeichnis mit Repository- und Arbeitsverzeichnisdateien angibt:


 define mgit = git --git-dir=../.git-$@ --work-tree=. endef 

Eingemachte Rezepte werden erstellt, wenn eine Befehlsfolge in mehreren Rezepten verwendet werden kann. Sie können aus mehreren Zeilen bestehen, von denen jede automatisch mit einer Registerkarte in den Rezepten hervorgehoben wird (genauer gesagt mit dem Symbol .RECIPEPREFIX ). In unserem Beispiel dient der Einzug nur zur besseren Lesbarkeit des Makefiles.
Während der Ausführung von Rezepten wird jede Zeile der vorbereiteten Sequenzen als separate Zeile des Rezepts interpretiert, dh sie können zu diesem Zweck insbesondere automatische Variablen verwenden .


Das vollständige Makefile sieht folgendermaßen aus:


 SITES := primer example SERVERHOST := example # .  punicode SERVERHOSTNAME := xn--e1afmkfd.xn--p1ai SERVERPATH := ~/archive all : $(SITES) .PHONY : $(SITES) # target-specific variables primer : DOMAIN := . primer : EXCLUDEDIRS := ,static example : DOMAIN := example.com ifeq ($(SERVERHOSTNAME),$(shell hostname)) # Server define mgit = git --git-dir=../.git-$@ --work-tree=. endef define init-git = mkdir -p $@ && \ $(get-data) && \ git init --bare ../.git-$@ && \ $(mgit) add . && \ $(mgit) commit -m "Initial commit of $@." endef define get-data = cd $@ && \ wget -r -nH -X $(EXCLUDEDIRS) --restrict-file-names=nocontrol $(DOMAIN) endef else # Workstation define init-git = git clone $(SERVERHOST):$(SERVERPATH)/.git-$@ $@ endef endif $(SITES) : ifeq ($(SERVERHOSTNAME),$(shell hostname)) # Server if [[ -d .git-$@ ]]; \ then \ $(get-data); \ $(mgit) add . && \ if [[ -n "`$(mgit) status --porcelain`" ]]; then \ $(mgit) commit -m "Update $@."; \ fi \ else \ $(init-git); \ fi else # Workstation if [[ -d $@/.git ]]; \ then \ cd $@ && git pull; \ else \ $(init-git); \ fi endif 

Im vierten Absatz gibt es zielspezifische Variablen: Für jedes Ziel können Sie einen eigenen Wert für diese Variable festlegen. Diese Werte werden auch in Abhängigkeit von den Voraussetzungen der einzelnen Ziele und den verwendeten vorbereiteten Rezepten übertragen. Das heißt, wir können sicher sein, dass das Rezept für jede Site mit dem richtigen Site-Namen und ihrem Verzeichnis ausgeführt wird.
Für jedes Projekt können wir unsere nicht archivierten Verzeichnisse über die Variable EXCLUDEDIRS übertragen oder leer lassen. Ebenso können Sie den Servernamen für die Archivierung von einem funktionierenden Computer ( SERVERHOST ) und den Pfad auf dem Server zum Verzeichnis mit dem Site-Archiv ( SERVERPATH ) ändern . In diesem Beispiel befinden sich der Einfachheit halber alle Sites auf demselben Server und werden im selben Verzeichnis archiviert.
Da jede Zeile des Rezepts (einschließlich der vorbereiteten) in einer separaten Shell ausgeführt wird , sodass der Übergang zum Verzeichnis für die folgenden Befehle gültig bleibt, verwenden wir den Operator "und" && und maskieren das Ende der Zeile \.


Als nächstes folgt das bedingte Makefile- Konstrukt : Mit dem Befehl shell hostname prüfen wir, ob make auf dem Server oder auf dem lokalen Computer ausgeführt wird. Zeilen, die den aktuellen Zweig der bedingten Direktive nicht erfüllen, werden vom Makefile vollständig ignoriert.


Der Unterschied zwischen lokalen und Server-Repositorys

Der lokale Computer wird hauptsächlich zum Speichern von Daten verwendet, daher kopieren wir nur Daten vom Server ( Git Pull ) auf diesen und zur Erleichterung der lokalen Arbeit mit Git (Anzeigen von Protokollen oder Dateiversionen) verwenden wir die Standard-Repository-Struktur (das übliche Repository im Ordner .git) )
In beiden Fällen ist ein einziger Befehl make ausreichend. Zum automatischen Kopieren können Sie den Cron- Scheduler verwenden. Um nicht jedes Mal das Kennwort für den Zugriff auf den Server einzugeben, werden SSH-Schlüssel generiert.


Um die Arbeit auf dem Server zu vereinfachen, können Sie aus dem Verzeichnis der aktuellen Site einen Alias- Git mit der angegebenen Konfiguration erstellen:


 alias mgit="git --work-tree=. --git-dir=../.git-${PWD##*/}" 

Die Variable $ {PWD ## * /} enthält den Namen des aktuellen Verzeichnisses ohne Pfad dazu und ist Teil des POSIX- Standards, dh sie kann in allen POSIX-fähigen Shells verwendet werden.


Eine bedingte Direktive kann auch in Rezepten verwendet werden. Die einzige Einschränkung besteht darin, dass Anfang und Ende nicht in verschiedenen Dateien enthalten sein dürfen.


Server

Nach dem Ausführen von make sieht das Archivverzeichnis folgendermaßen aus:


 $ ls -a . .. .git-example .git-primer Makefile example primer $ ls -a primer . .. index.html - - $ # ,     .    ./-  ./- 

Die nginx-Konfigurationsdatei für example.rf könnte folgendermaßen aussehen:


 server { server_name xn--e1afmkfd.xn--p1ai; charset utf-8; location = / { root /home/user/archive/primer; try_files /index.html =404; } location / { root /home/user/archive/primer; default_type "text/html"; try_files $uri =404; } location = /index.html { return 404; } } 

Der erste Speicherort entspricht der Hauptseite der Site, example.rf. Es wird von wget als index.html-Datei gespeichert. Ist dies nicht der Fall, wird ein Fehler 404 ausgegeben.


Für alle anderen URIs werden Dateien im Primer-Verzeichnis mit dem Namen URI überprüft. Wenn sie nicht gefunden werden, wird 404 zurückgegeben.


Um Doppelarbeit zu vermeiden, verweigern wir am Ende ausdrücklich den Zugriff auf den Link example.rf / index.html (404). Ein wenig mehr Details zu dieser Konfiguration finden Sie hier .


Fazit


Das Sichern von Websites kann mit den Standardtools wget , git , make erfolgen . Sie können alle Seiten einer Site kopieren oder Medien und eine Reihe anderer Dateien so genau ausschließen, wie es wget zulässt. In ähnlicher Weise können Sie mit .gitignore steuern, welche statischen Seiten dem Repository zur Sicherung hinzugefügt werden und welche nicht. Mit Makefile können Sie verschiedene Konfigurationen für verschiedene Projekte flexibel verwalten. Ein vollständiges Makefile-Beispiel für den Client und den Server oben enthält nur etwa 60 Zeilen.


Es wird davon ausgegangen, dass die Änderung und Hinzufügung von Website-Inhalten über Standardmechanismen erfolgt, dh CMS oder CMF werden dafür gestartet. Wenn dies selten vorkommt, können sie nach der Arbeit deaktiviert werden, wodurch Systemressourcen frei werden und gespeicherte statische Seiten angezeigt werden. Ein Beispiel für eine vollständigere Automatisierung verdient möglicherweise einen separaten Artikel.


Die vorgeschlagene Methode eignet sich hauptsächlich für kleine Projekte, die nur selten aktualisiert werden. Daher wurden Leistungs- und Sicherheitsprobleme hier kaum berücksichtigt. Da wir wget angewiesen haben, keine Zeichen aus dem URI zu entfernen, sollte für den Fall, dass beliebige Benutzer Dateien zur Site hinzufügen können, das Escapezeichen oder das Verbot des Hinzufügens sofort erfolgen.


Das Speichern von Versionen des Site-Inhalts kann auch über die Datenbank erfolgen, wenn die Seiten geändert werden. Dies erfordert jedoch die Versionsunterstützung durch CMF-Modelle sowie eine bessere Kontrolle über den Datenbankspeicherauszug (kopieren Sie ihn nach jeder Seitenbearbeitung vollständig). Bei der vorgeschlagenen Methode wird im Falle einer geringfügigen Änderung des Inhalts nur diese Änderung zum Repository hinzugefügt, und die Verwendung einer vollständigen Kopie der Datenbank ist nicht erforderlich. Darüber hinaus können die generierten statischen Seiten direkt vom Server verwendet oder in einem Browser angezeigt werden (Änderungen des Designs oder anderer Site-Codes werden ebenfalls kopiert).


Alternative Sicherungsprogramme sind hier aufgelistet. Um Mediendateien zu speichern und zu synchronisieren, sollten Sie auf git-annex achten. Das Trennen des .git-Repositorys vom Arbeitsbaum wurde auch erfolgreich zum Verwalten von Benutzerkonfigurationsdateien ( Punktedateien ) verwendet. Heute gibt es Server, die die Arbeit mit Git-Repositorys direkt unterstützen .

Source: https://habr.com/ru/post/de425259/


All Articles