Schritt 11: Den Code branchen

5.0 version
Maintained

Den Code branchen

Es gibt viele Möglichkeiten, den Workflow von Code-Änderungen in einem Projekt zu organisieren – Das direkte Arbeiten am Git Master-Branch und der direkte Einsatz im Produktivbetrieb ohne Tests ist aber nicht der beste Weg.

Beim Testen geht es nicht nur um Unit- oder Funktionale Tests, sondern auch um die Überprüfung des Anwendungsverhaltens mit echten Daten. Wenn Du oder Deine Stakeholder die Anwendung genau so benutzen können, wie sie für Endbenutzer*innen bereitgestellt wird, entsteht ein großer Vorteil, der Dir ermöglicht die Anwendung mit Vertrauen deployen zu können. Es ist besonders effizient, wenn nicht-technische Personen neue Funktionen validieren können.

Wir werden der Einfachheit halber (und zur Vermeidung von Wiederholungen) die nächsten Schritte auf dem Git Master-Branch fortführen, aber mal sehen, wie das besser funktionieren könnte.

Einen Git-Workflow einführen

Ein möglicher Workflow ist die Erstellung eines Branches pro neuem Feature oder Bugfix. Das ist einfach und effizient.

Deine Infrastruktur beschreiben

Du hast es vielleicht noch nicht bemerkt, aber die Infrastruktur parallel zum Code in Dateien zu speichern, kann sehr hilfreich sein. Docker und SymfonyCloud verwenden Konfigurationsdateien zur Beschreibung der Projektinfrastruktur. Wenn eine neue Funktion einen zusätzlichen Service benötigt, sind Änderungen im Code und auch die Änderungen der Infrastruktur Teil des selben Patches.

Branches erstellen

Der Workflow beginnt mit der Erstellung eines Git-Branches:

1
$ git branch -D sessions-in-redis || true
1
$ git checkout -b sessions-in-redis

Dieser Befehl erstellt einen sessions-in-redis-Branch, basierend auf dem master-Branch. Es „spaltet“ den Code und die Infrastrukturkonfiguration vom master-Branch ab.

Sessions in Redis speichern

Wie Du vielleicht schon am Namen des Branches erraten hast, wollen wir die Speicherung der Sessions vom Dateisystem auf Redis umstellen.

Die notwendigen Schritte, um dies zu verwirklichen, sind typisch:

  1. Erstelle einen Git-Branch;
  2. Aktualisiere bei Bedarf die Symfony-Konfiguration;
  3. Schreibe und/oder aktualisiere bei Bedarf etwas Code;
  4. Aktualisiere die PHP-Konfiguration (füge die Redis PHP-Erweiterung hinzu);
  5. Aktualisiere die Infrastruktur auf Docker und SymfonyCloud (füge den Redis-Dienst hinzu);
  6. Teste lokal;
  7. Teste remote;
  8. Führe den Branch mit dem Master-Branch zusammen;
  9. Deploye in die Produktivumgebung;
  10. Lösche den Branch.

Alle Änderungen, die für 2 bis 5 benötigt werden, können in einem Patch vorgenommen werden:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
--- a/.symfony.cloud.yaml
+++ b/.symfony.cloud.yaml
@@ -15,8 +15,13 @@ runtime:
 build:
     flavor: none

+variables:
+    php-ext:
+        redis: 5.3.1
+
 relationships:
     database: "db:postgresql"
+    redis: "rediscache:redis"

 web:
     locations:
--- a/.symfony/services.yaml
+++ b/.symfony/services.yaml
@@ -2,3 +2,6 @@ db:
     type: postgresql:11
     disk: 1024
     size: S
+
+rediscache:
+    type: redis:5.0
--- a/config/packages/framework.yaml
+++ b/config/packages/framework.yaml
@@ -7,7 +7,7 @@ framework:
     # Enables session support. Note that the session will ONLY be started if you read or write from it.
     # Remove or comment this section to explicitly disable session support.
     session:
-        handler_id: null
+        handler_id: '%env(REDIS_URL)%'
         cookie_secure: auto
         cookie_samesite: lax

--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -8,3 +8,7 @@ services:
             POSTGRES_PASSWORD: main
             POSTGRES_DB: main
         ports: [5432]
+
+    redis:
+        image: redis:5-alpine
+        ports: [6379]

Ist es nicht wunderschön?

Führe einen Docker-„Reboot“ durch, um den Redis-Dienst zu starten:

1
2
$ docker-compose stop
$ docker-compose up -d

Ich lasse Dich lokal testen, indem Du Dir die Website anschaust. Da es keine visuellen Veränderungen gibt und wir noch keine Sessions verwenden, sollte alles wie bisher funktionieren.

Einen Branch deployen

Bevor wir zum Produktivsystem deployen, sollten wir den Branch auf der gleichen Infrastruktur wie die Production-Environment testen. Wir sollten auch sicherstellen, dass für die Symfony prod-Environment alles gut funktioniert (die lokale Website hat die Symfony dev-Environment verwendet).

Stelle zunächst sicher, dass Deine Änderungen in den neuen Branch committet werden:

1
2
$ git add .
$ git commit -m'Configure redis sessions'

Lasst uns nun eine SymfonyCloud-Environment erstellen, die auf dem Git-Branch basiert:

1
$ symfony env:delete sessions-in-redis --no-interaction
1
$ symfony env:create

Dieser Befehl erstellt eine neue Environment:

  • Der Branch erbt den Code und die Infrastruktur vom aktuellen Git-Branch (sessions-in-redis);
  • Die Daten stammen von der Master-Environment (auch bekannt als Production oder Produktivumgebung), und zwar durch eine Momentaufnahme aller Servicedaten, einschließlich Dateien (z. B. von Benutzer*innen hochgeladene Dateien) und Datenbanken;
  • Ein neuer dedizierter Cluster wird erstellt, um den Code, die Daten und die Infrastruktur zu deployen.

Da das Deployment den gleichen Schritten folgt wie das Deployment in die Produktivumgebung, werden auch Datenbankmigrationen durchgeführt. Dies ist gleichzeitig eine gute Möglichkeit um sicherzugehen, dass die Migrationen mit echten Daten funktionieren.

Die Nicht-master-Environments sind der``master``-Environment sehr ähnlich, bis auf einige kleine Unterschiede: So werden beispielsweise E-Mails standardmäßig nicht gesendet.

Wenn das Deployment abgeschlossen ist, öffne den neuen Branch in einem Browser:

1
$ symfony open:remote

Beachte, dass alle SymfonyCloud-Befehle mit dem aktuellen Git-Branch arbeiten. Somit wird der Befehl die URL für den sessions-in-redis-Branch aufrufen. Die URL sieht dann so https://sessions-in-redis-xxx.eu.s5y.io/ aus.

Teste die Website auf dieser neuen Environment. Du solltest jetzt alle Daten sehen, die Du in der Master-Environment angelegt hast.

Wenn Du weitere Konferenzen in die master-Environment hinzufügst, werden diese nicht in der sessions-in-redis-Environment angezeigt und umgekehrt. Die Environments sind unabhängig und isoliert.

Wenn sich der Code auf Master weiterentwickelt, kannst Du diese Änderungen jederzeit mittels rebase in den aktuellen Branch integrieren und die aktualisierte Version deployen, wodurch die Konflikte sowohl für den Code als auch für die Infrastruktur gelöst werden.

Du kannst sogar die Daten von Master zurück in die sessions-in-redis-Environment synchronisieren:

1
$ symfony env:sync

Fehler von Deployments in die Produktivumgebung vermeiden

Standardmäßig verwenden alle SymfonyCloud-Environments die Einstellungen der master/prod-Environment (auch bekannt als die prod-Symfony-Environment). Auf diese Weise kannst Du die Anwendung unter realen Bedingungen testen. Dies gibt Dir das Gefühl, direkt auf Produktivsystemen zu entwickeln und zu testen, aber ohne den damit verbundenen Risiken. Das erinnert mich an die guten alten Zeiten, als wir Deployments noch über FTP gemacht haben.

Wenn ein Problem auftritt, möchtest Du vielleicht auf die dev-Symfony-Environment wechseln:

1
$ symfony env:debug

Wenn Du fertig bist, gehe zurück zu den Produktiveinstellungen:

1
$ symfony env:debug --off

Warnung

Aktiviere niemals die dev-Environment oder den Symfony Profiler im master-Branch; dies würde Deine Anwendung wirklich langsam machen und viele ernsthafte Sicherheitsschwachstellen öffnen.

Produktivinstallationen vor dem Deployment testen

Der Zugriff auf die zukünftige Version der Website mit echten Daten eröffnet viele Möglichkeiten: vom visuellen Regressionstest bis zum Performance-Test. Blackfire ist das perfekte Werkzeug für diese Aufgabe.

Lies den Schritt über „Performance“, um mehr darüber zu erfahren, wie Du Blackfire verwenden kannst, um Deinen Code vor dem Deployment zu testen.

In die Produktivumgebung mergen

Wenn Du mit den Änderungen im Branch zufrieden bist, führe den Code und die Infrastruktur wieder in den Git Master-Branch zurück:

1
2
$ git checkout master
$ git merge sessions-in-redis

Und deploye:

1
$ symfony deploy

Beim Deployment werden nur die Code- und Infrastrukturänderungen in die SymfonyCloud übertragen; die Daten werden in keiner Weise beeinträchtigt.

Aufräumen

Entferne zum Abschluss den Git-Branch und die SymfonyCloud-Environment:

1
2
$ git branch -d sessions-in-redis
$ symfony env:delete --env=sessions-in-redis --no-interaction

  • « Previous Schritt 10: Die Benutzeroberfläche erstellen
  • Next » Schritt 12: Mit Events arbeiten

This work, including the code samples, is licensed under a Creative Commons BY-NC-SA 4.0 license.