Entwicklungs- und Testprozess mit Docker und Gitlab CI

Ich schlage vor, das Transkript des Berichts von Alexander Sigachev von Inventos „Entwicklungs- und Testprozess mit Docker + Gitlab CI“ zu lesen.

Wer gerade erst mit der Implementierung des Entwicklungs- und Testprozesses auf Basis von Docker + Gitlab CI beginnt, stellt oft grundlegende Fragen. Wo soll ich anfangen? Wie organisiere ich? Wie testen?

Dieser Bericht ist gut, weil er strukturiert über den Entwicklungs- und Testprozess mit Docker und Gitlab CI spricht. Der Bericht selbst stammt aus dem Jahr 2017. Ich denke, dass Sie aus diesem Bericht die Grundlagen, die Methodik, die Idee und die Anwendungserfahrung lernen können.

Wen kümmert's, bitte unter die Katze.

Mein Name ist Alexander Sigachev. Ich arbeite für Inventos. Ich erzähle Ihnen von meinen Erfahrungen mit der Nutzung von Docker und wie wir es schrittweise in Projekten im Unternehmen implementieren.

Präsentationsthema: Entwicklungsprozess mit Docker und Gitlab CI.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Dies ist mein zweiter Vortrag über Docker. Zum Zeitpunkt des ersten Berichts haben wir Docker in der Entwicklung nur auf Entwicklermaschinen verwendet. Die Anzahl der Mitarbeiter, die Docker nutzten, betrug etwa 2-3 Personen. Nach und nach wurden Erfahrungen gesammelt und wir kamen ein Stück weiter. Link zu unserem erster Bericht.

Was steht in diesem Bericht? Wir werden unsere Erfahrungen darüber teilen, welchen Rake wir gesammelt haben und welche Probleme wir gelöst haben. Nicht überall war es schön, aber man durfte weiterziehen.

Unser Motto lautet: Docken Sie alles an, was uns in die Finger kommt.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Welche Probleme lösen wir?

Wenn es in einem Unternehmen mehrere Teams gibt, ist der Programmierer eine gemeinsame Ressource. Es gibt Phasen, in denen ein Programmierer aus einem Projekt abgezogen und für einige Zeit einem anderen Projekt überlassen wird.

Damit der Programmierer es schnell versteht, muss er den Quellcode des Projekts herunterladen und die Umgebung so schnell wie möglich starten, damit er die Probleme dieses Projekts weiter lösen kann.

Wenn Sie bei Null anfangen, gibt es normalerweise nur wenig Dokumentation im Projekt. Informationen zur Einrichtung sind nur für Oldtimer verfügbar. Die Mitarbeiter richten ihren Arbeitsplatz in ein bis zwei Tagen selbstständig ein. Um dies zu beschleunigen, haben wir Docker verwendet.

Der nächste Grund ist die Standardisierung der Einstellungen in der Entwicklung. Meiner Erfahrung nach ergreifen Entwickler immer die Initiative. In jedem fünften Fall wird eine benutzerdefinierte Domäne eingegeben, beispielsweise vasya.dev. Neben ihm sitzt seine Nachbarin Petya, deren Domain petya.dev ist. Sie entwickeln eine Website oder eine Komponente des Systems unter Verwendung dieses Domainnamens.

Wenn das System wächst und diese Domänennamen in die Konfigurationen gelangen, entsteht ein Entwicklungsumgebungskonflikt und der Site-Pfad wird neu geschrieben.

Das Gleiche geschieht mit den Datenbankeinstellungen. Jemand kümmert sich nicht um die Sicherheit und arbeitet mit einem leeren Root-Passwort. Bei der Installation fragte MySQL jemanden nach einem Passwort und das Passwort lautete 123. Es kommt häufig vor, dass sich die Datenbankkonfiguration abhängig vom Commit des Entwicklers ständig ändert. Jemand hat die Konfiguration korrigiert, jemand hat die Konfiguration nicht korrigiert. Es gab Tricks, als wir eine Art Testkonfiguration herausnahmen .gitignore und jeder Entwickler musste die Datenbank installieren. Das machte den Einstieg schwierig. Es ist unter anderem notwendig, sich an die Datenbank zu erinnern. Die Datenbank muss initialisiert werden, ein Passwort muss eingegeben werden, ein Benutzer muss registriert werden, eine Tabelle muss erstellt werden und so weiter.

Ein weiteres Problem sind unterschiedliche Versionen von Bibliotheken. Es kommt oft vor, dass ein Entwickler mit unterschiedlichen Projekten arbeitet. Es gibt ein Legacy-Projekt, das vor fünf Jahren begann (aus dem Jahr 2017 – Anm. d. Red.). Zum Zeitpunkt des Starts haben wir mit MySQL 5.5 begonnen. Es gibt auch moderne Projekte, bei denen wir versuchen, modernere Versionen von MySQL zu implementieren, zum Beispiel 5.7 oder älter (im Jahr 2017 – Anmerkung der Redaktion).

Jeder, der mit MySQL arbeitet, weiß, dass diese Bibliotheken Abhängigkeiten mit sich bringen. Es ist eher problematisch, 2 Basen zusammen zu betreiben. Zumindest ist es für alte Clients problematisch, eine Verbindung zur neuen Datenbank herzustellen. Dies wiederum führt zu mehreren Problemen.

Das nächste Problem besteht darin, dass ein Entwickler, wenn er auf einem lokalen Computer arbeitet, lokale Ressourcen, lokale Dateien und lokalen RAM verwendet. Die gesamte Interaktion zum Zeitpunkt der Entwicklung einer Problemlösung erfolgt im Rahmen der Tatsache, dass sie auf einer Maschine funktioniert. Ein Beispiel ist, wenn wir in Produktion 3 Backend-Server haben und der Entwickler Dateien im Stammverzeichnis speichert und Nginx von dort Dateien nimmt, um auf die Anfrage zu antworten. Wenn ein solcher Code in die Produktion gelangt, stellt sich heraus, dass die Datei auf einem der drei Server vorhanden ist.

Die Richtung der Microservices entwickelt sich jetzt. Wenn wir unsere großen Anwendungen in einige kleine Komponenten aufteilen, die miteinander interagieren. Dadurch können Sie Technologien für einen bestimmten Aufgabenstapel auswählen. Es ermöglicht Ihnen auch, Arbeit und Verantwortlichkeiten zwischen Entwicklern zu teilen.

Frondend-Entwickler, die auf JS entwickeln, haben fast keinen Einfluss auf das Backend. Der Backend-Entwickler wiederum entwickelt, in unserem Fall, Ruby on Rails und greift nicht in Frondend ein. Die Interaktion erfolgt über die API.

Als Bonus konnten wir mithilfe von Docker Ressourcen für Staging wiederverwenden. Jedes Projekt erforderte aufgrund seiner Besonderheiten bestimmte Einstellungen. Physisch war es notwendig, entweder einen virtuellen Server zuzuweisen und diese separat zu konfigurieren oder eine variable Umgebung gemeinsam zu nutzen, und Projekte könnten sich je nach Version der Bibliotheken gegenseitig beeinflussen.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Werkzeug. Was verwenden wir?

  • Docker selbst. Das Dockerfile beschreibt die Abhängigkeiten einer einzelnen Anwendung.
  • Docker-compose ist ein Bundle, das einige unserer Docker-Anwendungen zusammenfasst.
  • Wir verwenden GitLab, um den Quellcode zu speichern.
  • Zur Systemintegration nutzen wir GitLab-CI.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Der Bericht besteht aus zwei Teilen.

Im ersten Teil geht es darum, wie Docker auf den Rechnern der Entwickler ausgeführt wurde.

Im zweiten Teil geht es um die Interaktion mit GitLab, die Durchführung von Tests und die Einführung in Staging.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Docker ist eine Technologie, die es ermöglicht (mit einem deklarativen Ansatz), die notwendigen Komponenten zu beschreiben. Dies ist eine Beispiel-Dockerdatei. Hier erklären wir, dass wir vom offiziellen Docker-Image Ruby:2.3.0 erben. Es enthält Ruby Version 2.3 installiert. Wir installieren die erforderlichen Build-Bibliotheken und NodeJS. Wir beschreiben, dass wir ein Verzeichnis erstellen /app. Legen Sie das App-Verzeichnis als Arbeitsverzeichnis fest. In diesem Verzeichnis platzieren wir die erforderliche minimale Gemfile und Gemfile.lock. Anschließend erstellen wir die Projekte, die dieses Abhängigkeitsimage installieren. Wir geben an, dass der Container bereit ist, den externen Port 3000 abzuhören. Der letzte Befehl ist der Befehl, der unsere Anwendung direkt startet. Wenn wir den Projektstartbefehl ausführen, versucht die Anwendung, den angegebenen Befehl auszuführen und auszuführen.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Dies ist ein minimales Beispiel einer Docker-Compose-Datei. In diesem Fall zeigen wir, dass zwischen zwei Containern eine Verbindung besteht. Dies geschieht direkt im Datenbankdienst und im Webdienst. Unsere Webanwendungen benötigen in den meisten Fällen eine Art Datenbank als Backend zum Speichern von Daten. Da wir MySQL verwenden, ist das Beispiel MySQL – aber nichts hindert uns daran, eine andere Datenbank (PostgreSQL, Redis) zu verwenden.

Wir übernehmen das MySQL 5.7.14-Image ohne Änderungen aus der offiziellen Quelle des Docker-Hubs. Wir sammeln das Bild, das für unsere Webanwendung verantwortlich ist, aus dem aktuellen Verzeichnis. Beim ersten Start wird ein Bild für uns gesammelt. Dann führt es den Befehl aus, den wir hier ausführen. Wenn wir zurückgehen, werden wir sehen, dass der Startbefehl über Puma definiert wurde. Puma ist ein in Ruby geschriebener Dienst. Im zweiten Fall überschreiben wir. Dieser Befehl kann je nach unseren Bedürfnissen oder Aufgaben beliebig sein.

Wir beschreiben auch, dass wir einen Port auf unserem Entwickler-Hostcomputer von 3000 auf 3000 am Container-Port weiterleiten müssen. Dies geschieht automatisch über iptables und dessen Mechanismus, der direkt in Docker eingebettet ist.

Der Entwickler kann auch wie bisher auf jede verfügbare IP-Adresse zugreifen, beispielsweise ist 127.0.0.1 die lokale oder externe IP-Adresse der Maschine.

Die letzte Zeile besagt, dass der Webcontainer vom Datenbankcontainer abhängt. Wenn wir den Start des Webcontainers aufrufen, startet Docker-Compose zunächst die Datenbank für uns. Bereits beim Start der Datenbank (tatsächlich nach dem Start des Containers! Dies garantiert nicht die Bereitschaft der Datenbank) wird die Anwendung, unser Backend, gestartet.

Dies vermeidet Fehler, wenn die Datenbank nicht hochgefahren wird, und spart Ressourcen, wenn wir den Datenbankcontainer stoppen, wodurch Ressourcen für andere Projekte frei werden.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Was uns die Verwendung der Datenbank-Dockerisierung für das Projekt ermöglicht. Wir reparieren die MySQL-Version für alle Entwickler. Dies vermeidet einige Fehler, die auftreten können, wenn Versionen voneinander abweichen oder wenn sich Syntax, Konfiguration und Standardeinstellungen ändern. Dadurch können Sie einen gemeinsamen Hostnamen für die Datenbank, Login und Passwort angeben. Wir entfernen uns von dem Zoo der Namen und Konflikte in den Konfigurationsdateien, den wir zuvor hatten.

Wir haben die Möglichkeit, eine optimalere Konfiguration für die Entwicklungsumgebung zu verwenden, die von der Standardkonfiguration abweicht. MySQL ist standardmäßig für schwache Maschinen konfiguriert und seine Leistung ist im Auslieferungszustand sehr schlecht.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Mit Docker können Sie den Python-, Ruby-, NodeJS- und PHP-Interpreter der gewünschten Version verwenden. Wir machen die Verwendung einer Art Versionsmanager überflüssig. Bisher verwendete Ruby ein RPM-Paket, mit dem Sie die Version je nach Projekt ändern konnten. Dank des Docker-Containers ist es außerdem möglich, den Code reibungslos zu migrieren und ihn zusammen mit den Abhängigkeiten zu versionieren. Wir haben kein Problem damit, die Version des Interpreters und des Codes zu verstehen. Um die Version zu aktualisieren, senken Sie den alten Container ab und heben Sie den neuen Container an. Wenn etwas schief gelaufen ist, können wir den neuen Container absenken und den alten Container anheben.

Nach der Erstellung des Images sind die Container in Entwicklung und Produktion identisch. Dies gilt insbesondere für große Installationen.

Entwicklungs- und Testprozess mit Docker und Gitlab CI Im Frontend verwenden wir JavaScipt und NodeJS.

Jetzt haben wir das letzte Projekt auf ReacJS. Der Entwickler hat alles im Container ausgeführt und mithilfe von Hot-Reload entwickelt.

Als nächstes wird die JavaScipt-Assembly-Aufgabe gestartet und der in Statik kompilierte Code wird über Nginx bereitgestellt, wodurch Ressourcen gespart werden.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Hier habe ich das Schema unseres letzten Projekts gegeben.

Welche Aufgaben wurden gelöst? Wir mussten ein System entwickeln, mit dem mobile Geräte interagieren. Sie erhalten Daten. Eine Möglichkeit besteht darin, Push-Benachrichtigungen an dieses Gerät zu senden.

Was haben wir dafür getan?

Wir haben in die Anwendung solche Komponenten unterteilt wie: den Admin-Teil auf JS, das Backend, das über die REST-Schnittstelle unter Ruby on Rails funktioniert. Das Backend interagiert mit der Datenbank. Das generierte Ergebnis wird dem Client übergeben. Das Admin-Panel interagiert über die REST-Schnittstelle mit dem Backend und der Datenbank.

Wir hatten auch die Notwendigkeit, Push-Benachrichtigungen zu versenden. Zuvor hatten wir ein Projekt, das einen Mechanismus implementierte, der für die Übermittlung von Benachrichtigungen an mobile Plattformen verantwortlich ist.

Wir haben das folgende Schema entwickelt: Ein Operator vom Browser aus interagiert mit dem Admin-Panel, das Admin-Panel interagiert mit dem Backend, die Aufgabe besteht darin, Push-Benachrichtigungen zu senden.

Push-Benachrichtigungen interagieren mit einer anderen Komponente, die in NodeJS implementiert ist.

Es werden Warteschlangen erstellt und dann werden Benachrichtigungen gemäß ihrem Mechanismus gesendet.

Hier werden zwei Datenbanken gezeichnet. Derzeit nutzen wir mit Hilfe von Docker zwei unabhängige Datenbanken, die in keiner Beziehung zueinander stehen. Darüber hinaus verfügen sie über ein gemeinsames virtuelles Netzwerk und physische Daten werden in verschiedenen Verzeichnissen auf dem Rechner des Entwicklers gespeichert.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Das Gleiche, aber in Zahlen. Hier ist die Wiederverwendung von Code wichtig.

Wenn wir zuvor über die Wiederverwendung von Code in Form von Bibliotheken gesprochen haben, wird in diesem Beispiel unser Dienst, der auf Push-Benachrichtigungen reagiert, als vollständiger Server wiederverwendet. Es stellt eine API bereit. Und unsere Neuentwicklung interagiert bereits damit.

Zu diesem Zeitpunkt verwendeten wir Version 4 von NodeJS. Jetzt (im Jahr 2017 – Anmerkung der Redaktion) verwenden wir in jüngsten Entwicklungen Version 7 von NodeJS. Bei neuen Komponenten besteht kein Problem darin, neue Versionen von Bibliotheken einzubeziehen.

Bei Bedarf können Sie die NodeJS-Version über den Push-Benachrichtigungsdienst umgestalten und erhöhen.

Und wenn wir die API-Kompatibilität aufrechterhalten können, wird es möglich sein, sie durch andere Projekte zu ersetzen, die zuvor verwendet wurden.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Was benötigen Sie, um Docker hinzuzufügen? Wir fügen unserem Repository ein Dockerfile hinzu, das die notwendigen Abhängigkeiten beschreibt. In diesem Beispiel werden die Komponenten logisch zerlegt. Dies ist die Mindestausstattung eines Backend-Entwicklers.

Beim Erstellen eines neuen Projekts erstellen wir eine Docker-Datei und beschreiben das gewünschte Ökosystem (Python, Ruby, NodeJS). In Docker-Compose beschreibt es die notwendige Abhängigkeit – die Datenbank. Wir beschreiben, dass wir eine Datenbank dieser oder jener Version benötigen und dort und dort Daten speichern.

Wir verwenden einen separaten dritten Container mit Nginx, um statische Daten bereitzustellen. Es ist möglich, Bilder hochzuladen. Das Backend legt sie in einem vorbereiteten Volume ab, das auch in einem Container mit Nginx gemountet wird, was die Statik ergibt.

Um die Nginx- und MySQL-Konfiguration zu speichern, haben wir einen Docker-Ordner hinzugefügt, in dem wir die erforderlichen Konfigurationen speichern. Wenn ein Entwickler einen Git-Klon eines Repositorys auf seinem Computer erstellt, verfügt er bereits über ein Projekt, das für die lokale Entwicklung bereit ist. Es stellt sich keine Frage, welcher Port oder welche Einstellungen angewendet werden sollen.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Als nächstes haben wir mehrere Komponenten: Admin, Inform-API, Push-Benachrichtigungen.

Um all dies zu starten, haben wir ein weiteres Repository erstellt, das wir dockerized-app nannten. Im Moment verwenden wir vor jeder Komponente mehrere Repositories. Sie sind nur logisch unterschiedlich – in GitLab sieht es aus wie ein Ordner, aber auf dem Rechner des Entwicklers ist es ein Ordner für ein bestimmtes Projekt. Eine Ebene tiefer befinden sich die Komponenten, die kombiniert werden.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Dies ist nur ein Beispiel für den Inhalt der Dockerized-App. Wir bringen auch das Docker-Verzeichnis hierher, in das wir die für das Zusammenspiel aller Komponenten erforderlichen Konfigurationen eintragen. Es gibt eine README.md, die kurz beschreibt, wie das Projekt ausgeführt wird.

Hier haben wir zwei Docker-Compose-Dateien angewendet. Dies geschieht, um schrittweise ablaufen zu können. Wenn ein Entwickler mit dem Kern arbeitet, benötigt er keine Push-Benachrichtigungen, er startet einfach eine Docker-Compose-Datei und dementsprechend wird die Ressource gespart.

Wenn eine Integration mit Push-Benachrichtigungen erforderlich ist, werden docker-compose.yaml und docker-compose-push.yaml gestartet.

Da sich docker-compose.yaml und docker-compose-push.yaml in einem Ordner befinden, wird automatisch ein einzelnes virtuelles Netzwerk erstellt.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Beschreibung der Komponenten. Dies ist eine erweiterte Datei, die für die Sammlung von Komponenten verantwortlich ist. Was ist hier bemerkenswert? Hier stellen wir die Balancer-Komponente vor.

Dies ist ein vorgefertigtes Docker-Image, das Nginx und eine Anwendung ausführt, die den Docker-Socket überwacht. Dynamisch: Wenn Container ein- und ausgeschaltet werden, wird die Nginx-Konfiguration neu generiert. Wir verteilen die Handhabung von Komponenten durch Third-Level-Domainnamen.

Für die Entwicklungsumgebung verwenden wir die .dev-Domäne – api.informer.dev. Anwendungen mit einer .dev-Domäne sind auf dem lokalen Computer des Entwicklers verfügbar.

Darüber hinaus werden Konfigurationen auf jedes Projekt übertragen und alle Projekte werden gleichzeitig gemeinsam gestartet.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Grafisch stellt sich heraus, dass der Client unser Browser oder ein Tool ist, mit dem wir Anfragen an den Balancer stellen.

Der Domain Name Balancer bestimmt, welcher Container kontaktiert werden soll.

Es kann Nginx sein, das dem Administrator JS gibt. Dies kann Nginx sein, das die API bereitstellt, oder statische Dateien, die Nginx in Form von Bild-Uploads übergeben werden.

Das Diagramm zeigt, dass die Container durch ein virtuelles Netzwerk verbunden und hinter einem Proxy verborgen sind.

Auf dem Rechner des Entwicklers kann man mit Kenntnis der IP auf den Container zugreifen, diese nutzen wir aber grundsätzlich nicht. Ein direkter Zugriff ist praktisch nicht erforderlich.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Welches Beispiel sollten Sie sich ansehen, um Ihre Anwendung zu dockerisieren? Ein gutes Beispiel ist meiner Meinung nach das offizielle Docker-Image für MySQL.

Es ist ziemlich herausfordernd. Es gibt viele Versionen. Aber seine Funktionalität ermöglicht es Ihnen, viele Bedürfnisse abzudecken, die im Laufe der Weiterentwicklung entstehen können. Wenn Sie sich die Zeit nehmen und herausfinden, wie das alles zusammenwirkt, dann werden Sie meiner Meinung nach keine Probleme bei der Selbstumsetzung haben.

Hub.docker.com enthält normalerweise Links zu github.com, das Rohdaten direkt enthält, aus denen Sie das Image selbst erstellen können.

Darüber hinaus befindet sich in diesem Repository ein docker-endpoint.sh-Skript, das für die Erstinitialisierung und die weitere Verarbeitung des Anwendungsstarts verantwortlich ist.

Auch in diesem Beispiel besteht die Möglichkeit zur Konfiguration mithilfe von Umgebungsvariablen. Indem wir beim Ausführen eines einzelnen Containers oder über Docker-Compose eine Umgebungsvariable definieren, können wir sagen, dass wir ein leeres Passwort festlegen müssen, damit Docker auf MySQL rooten kann, oder was auch immer wir wollen.

Es besteht die Möglichkeit, ein zufälliges Passwort zu erstellen. Wir sagen, wir brauchen einen Benutzer, wir müssen ein Passwort für den Benutzer festlegen und wir müssen eine Datenbank erstellen.

In unseren Projekten haben wir die Docker-Datei, die für die Initialisierung verantwortlich ist, leicht vereinheitlicht. Dort haben wir es an unsere Bedürfnisse angepasst, sodass es lediglich eine Erweiterung der Benutzerrechte ist, die die Anwendung verwendet. Dadurch konnten wir später einfach eine Datenbank über die Anwendungskonsole erstellen. Ruby-Anwendungen verfügen über einen Befehl zum Erstellen, Ändern und Löschen von Datenbanken.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Dies ist ein Beispiel dafür, wie eine bestimmte Version von MySQL auf github.com aussieht. Sie können die Docker-Datei öffnen und sehen, wie die Installation dort voranschreitet.

docker-endpoint.sh ist das Skript, das für den Einstiegspunkt verantwortlich ist. Während der Erstinitialisierung sind einige Vorbereitungsschritte erforderlich, und alle diese Aktionen werden einfach im Initialisierungsskript ausgeführt.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Wir gehen zum zweiten Teil über.

Um die Quellcodes zu speichern, sind wir auf Gitlab umgestiegen. Dies ist ein ziemlich leistungsfähiges System mit einer visuellen Oberfläche.

Eine der Komponenten von Gitlab ist Gitlab CI. Sie können damit eine Befehlsfolge beschreiben, die später zum Organisieren eines Codebereitstellungssystems oder zum Ausführen automatischer Tests verwendet wird.

Gitlab CI 2-Vortrag https://goo.gl/uohKjI - Bericht vom Ruby Russia Club - ziemlich ausführlich und vielleicht interessiert es Sie.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Nun schauen wir uns an, was erforderlich ist, um Gitlab CI zu aktivieren. Um Gitlab CI zu starten, müssen wir lediglich die Datei .gitlab-ci.yml im Stammverzeichnis des Projekts ablegen.

Hier beschreiben wir, dass wir eine Folge von Zuständen wie einen Test oder eine Bereitstellung ausführen möchten.

Wir führen Skripte aus, die docker-compose direkt aufrufen, um unsere Anwendung zu erstellen. Dies ist nur ein Backend-Beispiel.

Als nächstes sagen wir, dass es notwendig ist, Migrationen durchzuführen, um die Datenbank zu ändern und Tests durchzuführen.

Wenn die Skripte korrekt ausgeführt werden und kein Fehlercode zurückgegeben wird, fährt das System entsprechend mit der zweiten Phase der Bereitstellung fort.

Die Bereitstellungsphase ist derzeit für das Staging implementiert. Wir haben keinen Neustart ohne Ausfallzeiten organisiert.

Wir löschen alle Behälter gewaltsam und heben dann alle Behälter, die in der ersten Phase des Tests gesammelt wurden, wieder an.

Wir führen für die aktuelle Umgebungsvariable die von den Entwicklern geschriebenen Datenbankmigrationen aus.

Es gibt einen Hinweis, dass dies nur für den Hauptzweig gilt.

Beim Ändern anderer Zweige wird dies nicht ausgeführt.

Es besteht die Möglichkeit, Rollouts nach Filialen zu organisieren.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Um dies weiter zu organisieren, müssen wir Gitlab Runner installieren.

Dieses Dienstprogramm ist in Golang geschrieben. Es handelt sich um eine einzelne Datei, wie in der Golang-Welt üblich, die keinerlei Abhängigkeiten erfordert.

Beim Start registrieren wir den Gitlab Runner.

Den Schlüssel erhalten wir im Gitlab-Webinterface.

Dann rufen wir den Initialisierungsbefehl auf der Kommandozeile auf.

Gitlab Runner interaktiv einrichten (Shell, Docker, VirtualBox, SSH)

Der Code auf Gitlab Runner wird bei jedem Commit ausgeführt, abhängig von der .gitlab-ci.yml-Einstellung.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Wie es optisch in Gitlab im Webinterface aussieht. Nachdem wir GItlab CI verbunden haben, haben wir eine Flagge, die den aktuellen Status des Builds anzeigt.

Wir sehen, dass vor 4 Minuten ein Commit durchgeführt wurde, der alle Tests bestanden hat und keine Probleme verursacht hat.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Wir können uns die Builds genauer ansehen. Hier sehen wir, dass bereits zwei Staaten bestanden haben. Teststatus und Bereitstellungsstatus beim Staging.

Wenn wir auf einen bestimmten Build klicken, wird eine Konsolenausgabe der Befehle angezeigt, die gemäß .gitlab-ci.yml im Prozess ausgeführt wurden.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

So sieht unsere Produktgeschichte aus. Wir sehen, dass es erfolgreiche Versuche gab. Wenn Tests übermittelt werden, wird nicht mit dem nächsten Schritt fortgefahren und der Staging-Code wird nicht aktualisiert.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Welche Aufgaben haben wir beim Staging gelöst, als wir Docker implementiert haben? Unser System besteht aus Komponenten und wir mussten nur einen Teil der Komponenten neu starten, die im Repository aktualisiert wurden, und nicht das gesamte System.

Dazu mussten wir alles in separate Ordner zerlegen.

Nachdem wir dies getan hatten, hatten wir ein Problem damit, dass Docker-Compose für jeden Papa einen eigenen Netzwerkraum erstellt und die Komponenten des Nachbarn nicht sieht.

Um uns zurechtzufinden, haben wir das Netzwerk in Docker manuell erstellt. In Docker-compose wurde geschrieben, dass Sie für dieses Projekt ein solches Netzwerk verwenden.

Somit sieht jede Komponente, die mit diesem Netz beginnt, Komponenten in anderen Teilen des Systems.

Das nächste Problem ist die Aufteilung der Bereitstellung auf mehrere Projekte.

Denn damit das alles schön und möglichst produktionsnah aussieht, empfiehlt es sich, Port 80 oder 443 zu verwenden, der überall im WEB verwendet wird.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Wie haben wir es gelöst? Wir haben allen größeren Projekten einen Gitlab Runner zugewiesen.

Mit Gitlab können Sie mehrere verteilte Gitlab Runner ausführen, die einfach alle Aufgaben chaotisch nacheinander übernehmen und ausführen.

Damit wir kein Haus haben, haben wir die Gruppe unserer Projekte auf einen Gitlab Runner beschränkt, der mit unseren Volumina problemlos zurechtkommt.

Wir haben nginx-proxy in ein separates Startskript verschoben und Raster für alle darin enthaltenen Projekte hinzugefügt.

Unser Projekt verfügt über ein Raster und der Balancer verfügt über mehrere Raster nach Projektnamen. Es kann weitere Domänennamen als Proxy verwenden.

Unsere Anfragen kommen über die Domäne an Port 80 und werden in eine Containergruppe aufgelöst, die diese Domäne bedient.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Welche weiteren Probleme gab es? Alle Container werden standardmäßig als Root ausgeführt. Dabei handelt es sich um Root, der nicht mit dem Root-Host des Systems übereinstimmt.

Wenn Sie jedoch den Container betreten, wird dieser zum Root-Benutzer und die Datei, die wir in diesem Container erstellen, erhält Root-Rechte.

Wenn der Entwickler den Container betreten und dort einige Befehle ausgeführt hat, die Dateien generieren, und dann den Container verlassen hat, dann hat er eine Datei in seinem Arbeitsverzeichnis, auf die er keinen Zugriff hat.

Wie kann es gelöst werden? Sie können Benutzer hinzufügen, die sich im Container befinden.

Welche Probleme traten auf, als wir den Benutzer hinzugefügt haben?

Beim Erstellen eines Benutzers haben wir häufig nicht dieselbe Gruppen-ID (UID) und Benutzer-ID (GID).

Um dieses Problem im Container zu lösen, verwenden wir Benutzer mit der ID 1000.

In unserem Fall fiel dies mit der Tatsache zusammen, dass fast alle Entwickler das Ubuntu-Betriebssystem verwenden. Und unter Ubuntu hat der erste Benutzer die ID 1000.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Haben wir Pläne?

Lesen Sie die Docker-Dokumentation. Das Projekt entwickelt sich aktiv weiter, die Dokumentation ändert sich. Die Daten, die vor zwei, drei Monaten eingegangen sind, veralten bereits langsam.

Einige der Probleme, die wir gelöst haben, sind möglicherweise bereits mit Standardmitteln gelöst.

Ich möchte also schon weiter gehen, um direkt zur Orchestrierung zu gelangen.

Ein Beispiel ist der integrierte Mechanismus von Docker namens Docker Swarm, der sofort einsatzbereit ist. Ich möchte etwas in der Produktion ausführen, das auf der Docker Swarm-Technologie basiert.

Das Spawnen von Containern erschwert die Arbeit mit Protokollen. Jetzt sind die Protokolle isoliert. Sie sind über Container verteilt. Eine der Aufgaben besteht darin, einen bequemen Zugriff auf die Protokolle über die Weboberfläche zu ermöglichen.

Entwicklungs- und Testprozess mit Docker und Gitlab CI

Source: habr.com

Kommentar hinzufügen