it-swarm.com.de

Ist die Verwendung von Git für die Bereitstellung einer schlechten Praxis?

Ich neige dazu, Git zum Bereitstellen von Produktionscode auf dem Webserver zu verwenden. Das bedeutet normalerweise, dass irgendwo ein Master-Git-Repository an einem Ort gehostet wird, auf den über ssh zugegriffen werden kann, und der Produktionsserver dieses geklonte Repository bedient und gleichzeitig den Zugriff auf .git/ Und .gitignore Beschränkt. Wenn ich es aktualisieren muss, ziehe ich einfach vom Master-Repository zum Repository des Servers. Dies hat mehrere Vorteile:

  1. Wenn jemals etwas schief geht, ist es extrem einfach, auf eine frühere Revision zurückzugreifen - so einfach wie das Auschecken.
  2. Wenn eine der Quellcodedateien geändert wird, so einfach wie git status, Und wenn das Repository des Servers geändert wurde, wird dies beim nächsten Versuch offensichtlich.
  3. Dies bedeutet, dass noch eine Kopie des Quellcodes vorhanden ist, falls schlechte Dinge passieren.
  4. Das Aktualisieren und Zurücksetzen ist einfach und sehr schnell.

Dies könnte jedoch einige Probleme haben:

  • Wenn der Webserver aus irgendeinem Grund entscheidet, dass er das Verzeichnis .git/ Bereitstellen soll, ist der gesamte Quellcode, der vorhanden war und ist, für alle lesbar. Historisch gesehen gab es einige (große) Unternehmen, die diesen Fehler gemacht haben. Ich verwende die Datei .htaccess, Um den Zugriff einzuschränken. Daher glaube ich, dass im Moment keine Gefahr besteht. Vielleicht ist ein Integrationstest in Ordnung, der sicherstellt, dass niemand den Ordner .git/ Lesen kann?

  • Jeder, der versehentlich Lesezugriff auf den Ordner erhält, erhält auch Zugriff auf jede frühere Version des früheren Quellcodes. Aber es sollte nicht viel schlimmer sein, als Zugang zur vorliegenden Version zu haben. Schließlich sind diese Überarbeitungen per Definition veraltet.

Alles in allem glaube ich, dass die Verwendung von Git zum Bereitstellen von Code für die Produktion einigermaßen sicher und viel einfacher ist als rsync, ftp oder einfach nur zu kopieren. Was denken Sie?

109
Septagram

Ich würde sogar in Betracht ziehen, Git für die Bereitstellung zu verwenden , eine sehr gute Praxis .

Die beiden von Ihnen aufgelisteten Probleme haben sehr wenig mit der Verwendung von git für die Bereitstellung selbst zu tun. Ersatz .git/ für die Konfigurationsdatei, die Datenbankkennwörter enthält, und Sie haben das gleiche Problem. Wenn ich Lesezugriff auf Ihr Webstamm habe, habe ich Lesezugriff auf alles, was darin enthalten ist. Dies ist ein Problem der Serverhärtung, das Sie mit Ihrer Systemadministration besprechen müssen.

git bietet einige sehr attraktive Vorteile, wenn es um Sicherheit geht.

  1. Sie können ein System für die Bereitstellung in der Produktion erzwingen. Ich würde sogar ein post-receive Hook zur automatischen Bereitstellung in der Produktion, wenn ein Commit für master vorgenommen wird. Ich gehe natürlich von einem Workflow ähnlich git flow aus.

  2. mit git ist es extrem einfach, den in der Produktion bereitgestellten Code auf eine frühere Version zurückzusetzen, wenn ein Sicherheitsproblem auftritt. Dies kann hilfreich sein, um den Zugriff auf geschäftskritische Sicherheitslücken zu blockieren, für deren Behebung Sie Zeit benötigen.

  3. Sie können ein System erzwingen, in dem Ihre Entwickler die von ihnen vorgenommenen Commits unterzeichnen müssen. Dies kann dabei helfen, festzustellen, wer was für die Produktion bereitgestellt hat, wenn eine absichtliche Sicherheitslücke gefunden wird.

77
user10211

Es ist nichts Falsches daran, von einem Git-Repo aus bereitzustellen. Tatsächlich ist dies eine weit verbreitete Praxis und, wie Sie sagen, viel weniger fehleranfällig als das Kopieren von Dateien über FTP oder Rsync.

Angesichts der von Ihnen angegebenen Informationen möchte ich folgende Punkte beachten:

  • Ziehen Sie nicht nur den neuesten Master ein. Die Produktion sollte über ein Release-Tag bereitgestellt werden. Verwenden Sie git flow oder ähnliches, um mehr Informationen über die Bereitstellung des Codes und die Erstellung der Tags zu erhalten. Da Tags zu einem bestimmten Zeitpunkt eine unveränderliche Referenz auf Ihren Code sind, ist sie stabiler als der Verweis auf einen Hauptzweig, der durch ein fehlerhaftes Festschreiben aktualisiert werden könnte.

  • Für die Bereitstellung des .git-Verzeichnisses sollte dies kein großes Problem sein. Leiten Sie einfach alles, was mit .git vorangestellt ist, auf 404 in .htaccess um.

  • Ihre Git-Authentifizierung sollte auf SSH-Schlüsseln basieren, damit keine Repo-Passwörter auf dem Server gespeichert werden müssen.

Hurra für Git-Deployment-Workflows!

26
Matt Surabian

Du kannst den ... benutzen --separate-git-dir=<git dir> Argument beim Aufruf von Git-Klon . Dadurch wird ein symbolischer Link in das .git Verzeichnis (symbolisch für Git, ich glaube nicht, dass es ein symbolischer Link zu Ihrem Betriebssystem ist), und Sie können das <git dir> an einen Ort außerhalb des Dokumentstamms.

8
Brendon

Ich werde hier der Meinung der Bevölkerung nicht zustimmen. Git dient der Versionskontrolle, nicht der Bereitstellung/CI.

Die Methoden, die hier empfohlen werden, eignen sich gut für kleine Projekte, lassen sich aber im Allgemeinen nicht sehr gut skalieren.

... was nicht heißt, dass Sie nicht weiter machen sollten, was Sie tun. Denken Sie im Verlauf Ihrer Karriere daran, dass die Projekte, an denen Sie arbeiten, wahrscheinlich aus einem rein git-basierten Bereitstellungsworkflow herauswachsen werden.

Der wichtigste Paradigmenwechsel besteht darin, nicht mehr über die Bereitstellung von Zweigen nachzudenken, sondern über die Bereitstellung von Build-Ergebnissen nachzudenken und Umgebungsabhängigkeiten einzufügen, um Ihre Infrastruktur von Ihrer Verzweigungsstrategie zu entkoppeln.

Verwenden Sie beispielsweise das obige Paradigma zum Bereitstellen von Dateien und zum Zurücksetzen. Wenn Sie waren Dateien bereitstellen, können Sie mehrere Versionen der Anwendung auf dem Produktionsserver behalten. Wenn Sie ein Rollback durchführen müssen, können Sie Ihren Webserver auf eine ältere Version verweisen, indem Sie das Webstammverzeichnis erneut verknüpfen. Zwei Shell-Befehle, Mikrosekunden Ausfallzeit, weniger Fehlerfreiheit als bei Verwendung von git.

Ein weiteres Beispiel: Sie haben den Standard-Dev-Zweig> Staging-Zweig> Master-Workflow mit jeweils einem Server. Sie haben Dinge bereit für die Entwicklung, aber einige andere Dinge zur Bereitstellung haben die Qualitätssicherung fehlgeschlagen. Sie müssen also einige hässliche Vorgänge ausführen - die fehlerhaften Commits von der Bühne entfernen, die Phase erneut bereitstellen sowie die fehlerhaften Commits in der Entwicklung entfernen oder beheben und hoffen, dass Entwicklung und Staging nicht nicht synchron sind.

Was ist stattdessen, wenn Sie einen Release-Zweig vom Master abschneiden, das Material, das für diesen Release-Zweig bereit ist, zusammenführen und das Ergebnis erstellen, einen Testserver in AWS hochfahren und das Ergebnis dort bereitstellen, Ihre Qualitätssicherung und Funktionstests ausführen dieser temporäre Staging-Server und dann das gleiche Ergebnis in den Produktionscluster übertragen und bereitgestellt? Deaktivieren Sie dann die temporäre Staging-Box, die Sie hochgefahren haben, führen Sie die Version in Master zusammen und kennzeichnen Sie Master mit einer Release-Nummer.

Offensichtlich sind das extreme Beispiele. Normalerweise ist es nicht so sauber, selbst wenn wir es möchten - Sie müssen wahrscheinlich einige Build-Prozesse in der Zielumgebung ausführen, da Datenbankänderungen erforderlich sind. Und wenn Sie zwischen den Versionen nicht-idempotente Datenbankmods haben, wird das Rollback nicht so einfach sein, egal welche Methode Sie verwenden, da Sie die Datenbank zurücksetzen müssen (versuchen Sie im Allgemeinen, eine idempotente Datenbank bereitzustellen Änderungen, und entfernen Sie dann die veralteten Datenbankbits in einer späteren Version, nachdem Sie sicher sind, dass sie nicht mehr im Anwendungsfluss sind.

Wie auch immer, ich denke, was ich vorhabe, ist meine Antwort auf "Ist die Verwendung von Git für die Bereitstellung eine schlechte Praxis?" ist im Allgemeinen "Ja", genauso wie die Verwendung von Stützrädern für das Fahrradfahren schlecht ist. Es ist eine Verbesserung, wenn Sie Ihren Arsch wiederholt auf dem Beton platzen lassen, aber Sie wachsen hoffentlich irgendwann heraus.

8
siliconrockstar

Ein alternativer Ansatz, den ich zuvor gewählt habe, ähnelt Terry Chias Kommentar zu Post-Receive-Hooks.

Git hat eine Reihe von Hooks , mit denen alle Arten von Aufgaben vor/während/nach mehreren verschiedenen Aktionen ausgeführt werden können.

Erstellen Sie ein nacktes Repository an einer anderen Stelle als in Ihrem Webordner. Das nackte Repository kann dann als remote to Push to verwendet werden, und ein Post-Receive-Hook kann ausgelöst werden, um den neuen Code in ein angegebenes Verzeichnis auszuchecken.

Dieser Ansatz hat einige Vorteile: Der Bereitstellungsort fungiert als "Einbahnstraße", in der Code die Quellcodeverwaltung durchlaufen muss, um in die Produktion zu gelangen. Sie können verschiedene Zweige/Versionen an verschiedenen Standorten bereitstellen (alle aus demselben Bare-Repo). Es bietet auch eine schöne einfache Möglichkeit zum Rollback mit der Standard-Git-Kaufabwicklung. Eine Einschränkung/Konsequenz davon ist jedoch, dass Codeänderungen auf dem Server nicht in git wiedergegeben werden (nackte Repositorys haben keine Arbeitsverzeichnisse), sodass Sie manuell git --work-tree=/path/to/code status Ausführen müssen, um Änderungen zu sehen ( aber du solltest sowieso nicht den Produktionscode ändern, oder?)

5
russdot

Ich stimme Terry Chia zu, dass es eine sehr gute Praxis ist. Es stellt sicher:

  • dass die vorhandene Revision die richtige ist,
  • mit allen benötigten Dateien und prüft die Vollständigkeit der Version,
  • machen Sie den Bereitstellungsvorgang schnell und einfach

Aber ich muss hinzufügen, dass es Vorbehalte gibt, die ich gerne teilen möchte.

Normalerweise legen Sie in ein Git-Repository Folgendes ab:

  • code,
  • docs,
  • unit Testing,
  • bereitstellungsskripte,
  • integrationswerkzeuge,
  • .deb Archive,
  • sQL-Patches
  • oder solche Sachen, und vielleicht ein paar andere Sachen

Nun, in der Produktion wollen Sie nur den Code!

Denn Dokumente, Komponententests, Tools oder .deb-Archive können viel Speicherplatz beanspruchen und haben in der Produktion nichts zu tun.

Mit Subversion (vor Version 1.7) können Sie nur das src/ Verzeichnis und Sie haben alle Vorteile. Aber mit Subversion> 1.7 und mit Git können Sie das nicht tun.

Eine Alternative wäre die Verwendung von Git-Submodulen, um diese Art von Architektur zu erstellen: project repo |- doc |- src -> submodule to project-src repo. \ tests Aber dann würden Ihr Projekt/Ihre Tests und Ihr Projekt-Quellcode nicht synchronisiert und das wäre wirklich scheiße.

Die Lösung wäre dann, "sparse checkout" zu verwenden, siehe: https://stackoverflow.com/questions/600079/how-do-i-clone-a-subdirectory-only-of-a-git- Repository

Sie können also git verwenden, aber achten Sie bitte auf diese Nachteile.

3
Thibault

Hier ist das Skript, mit dem ich Git zu Push to Prod mache.

https://Gist.github.com/Zamicol/f160d05dd22c9eb25031

Es wird davon ausgegangen, dass alles, was an die Hauptniederlassung gesendet wird, für die Produktion bereit ist. Alle anderen geschobenen Zweige werden ignoriert. Sie können dieses Hook-Skript an Ihre Bedürfnisse anpassen.

Was Ihre Bedenken betrifft, platziere ich mein Git-Verzeichnis unter/var/git und meine Produktionsdateien an einer anderen Stelle (wie/var/www) und beschränke den Zugriff auf diese Verzeichnisse.

Sie können Ihr Git-Repo auch auf einem von Ihrem Produktionsserver getrennten Server haben und dann im obigen Skript scp und ssh verwenden, um Ihre Dateien vom Git-Server auf den Produktionsserver zu verschieben. Auf diese Weise können Sie weiterhin git verwenden, um Push to prod zu erstellen, während Sie Ihren Code von Ihrer Produktion trennen.

1
Zamicol