Schritt 7: Eine Datenbank einrichten

5.0 version
Maintained

Eine Datenbank einrichten

Auf der Website des Konferenzgästebuchs geht es darum, während der Konferenzen Feedback zu sammeln. Wir müssen die Kommentare von den Konferenzteilnehmer*innen in einem permanenten Speicher ablegen.

Ein Kommentar lässt sich am besten durch eine feste Datenstruktur beschreiben: Autor*in, E-Mail, der Text des Feedbacks und ein optionales Foto. Das ist die Art Daten, die am besten in einer traditionellen relationalen Datenbank gespeichert wird.

PostgreSQL ist das Datenbanksystem unserer Wahl.

PostgreSQL zu Docker Compose hinzufügen

Auf unserem lokalen Rechner haben wir uns entschieden, Docker zur Verwaltung von Services zu verwenden. Erstelle eine docker-compose.yaml-Datei und füge PostgreSQL als Service hinzu:

docker-compose.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
version: '3'

services:
    database:
        image: postgres:11-alpine
        environment:
            POSTGRES_USER: main
            POSTGRES_PASSWORD: main
            POSTGRES_DB: main
        ports: [5432]

Dadurch wird ein PostgreSQL-Server in der Version 11 installiert und einige Environment-Variablen konfiguriert, die den Datenbanknamen und die Credentials (Anmeldeinformationen) steuern. Die Werte spielen keine Rolle.

Wir stellen auch den PostgreSQL-Port (5432) des Containers dem lokalen Host zur Verfügung. Das wird uns helfen, von unserer Maschine aus auf die Datenbank zuzugreifen.

Bemerkung

Die pdo_pgsql-Erweiterung sollte installiert worden sein, als PHP in einem vorherigen Schritt eingerichtet wurde.

Docker Compose starten

Starte Docker Compose im Hintergrund (-d):

1
$ docker-compose up -d

Warte ein wenig, bis die Datenbank hochgefahren ist und überprüfe, ob alles in Ordnung ist:

1
2
3
4
5
$ docker-compose ps

        Name                      Command              State            Ports
---------------------------------------------------------------------------------------
guestbook_database_1   docker-entrypoint.sh postgres   Up      0.0.0.0:32780->5432/tcp

Überprüfe die Docker Compose logs wenn es keine aktiven Container gibt oder wenn die State-Spalte nicht Up anzeigt:

1
$ docker-compose logs

Zugriff auf die lokale Datenbank

Die Verwendung des psql-Befehls im Terminal kann sich von Zeit zu Zeit als nützlich erweisen. Aber Du musst dir die Anmeldeinformationen und den Datenbanknamen merken. Weniger offensichtlich ist, dass Du auch den lokalen Port kennen musst, mit dem die Datenbank auf dem Host läuft. Docker wählt einen zufälligen Port, so dass Du an mehr als einem Projekt gleichzeitig mit PostgreSQL arbeiten kannst (der lokale Port ist Teil der Ausgabe von docker-compose ps).

Wenn Du psql über die Symfony CLI aufrufst, musst Du dir nichts merken.

Die Symfony CLI erkennt automatisch die für das Projekt ausgeführten Docker-Dienste und stellt die Environment-Variablen bereit, die psql für die Verbindung zur Datenbank benötigt.

Dank dieser Konventionen ist der Zugriff auf die Datenbank via symfony run viel einfacher:

1
$ symfony run psql

Bemerkung

Wenn Du die psql Binärdatei nicht auf Deinem lokalen Host hast, kannst Du sie auch über docker laufen lassen:

1
$ docker exec -it guestbook_database_1 psql -U main -W main

PostgreSQL zur SymfonyCloud hinzufügen

Für die Produktiv-Infrastruktur auf SymfonyCloud sollte das Hinzufügen eines Dienstes wie PostgreSQL in der aktuell leeren .symfony/services.yaml-Datei erfolgen:

.symfony/services.yaml
1
2
3
4
db:
    type: postgresql:11
    disk: 1024
    size: S

Der db Dienst ist eine PostgreSQL-Datenbank in der Version 11 (wie für Docker), die wir auf einem kleinen Container mit einer Kapazität von 1 GB bereitstellen wollen.

Wir müssen auch die DB mit dem Anwendungscontainer „verknüpfen“, was in .symfony.cloud.yaml beschrieben ist:

.symfony.cloud.yaml
1
2
relationships:
    database: "db:postgresql"

Der db Dienst vom Typ postgresql wird auf dem Anwendungscontainer mit database referenziert.

Der letzte Schritt besteht darin, die pdo_pgsql Erweiterung zur PHP-Laufzeit hinzuzufügen:

.symfony.cloud.yaml
1
2
3
4
runtime:
    extensions:
        - pdo_pgsql
        # other extensions here

Das sind alle Unterschiede in der .symfony.cloud.yaml:

patch_file
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
--- a/.symfony.cloud.yaml
+++ b/.symfony.cloud.yaml
@@ -4,6 +4,7 @@ type: php:7.3

 runtime:
     extensions:
+        - pdo_pgsql
         - apcu
         - mbstring
         - sodium
@@ -12,6 +13,9 @@ runtime:
 build:
     flavor: none

+relationships:
+    database: "db:postgresql"
+
 web:
     locations:
         "/":

Commite diese Änderungen und deploye sie dann erneut zur SymfonyCloud:

1
2
3
$ git add .
$ git commit -m'Configuring the database'
$ symfony deploy

Zugriff auf die SymfonyCloud-Datenbank

PostgreSQL läuft nun sowohl lokal über Docker als auch in der Produktivumgebung auf SymfonyCloud.

Wie wir gerade gesehen haben, verbindet symfony run psql sich automatisch mit der von Docker gehosteten Datenbank – Dank der Environment-Variablen, die von symfony run bereitgestellt werden.

Wenn Du eine Verbindung zur PostgreSQL-Datenbank herstellen möchtest, die auf den Production-Containern gehostet wird, kannst Du einen SSH-Tunnel zwischen dem lokalen Computer und der SymfonyCloud-Infrastruktur öffnen:

1
$ symfony tunnel:open --expose-env-vars

Standardmäßig werden SymfonyCloud-Dienste nicht als Environment-Variablen auf dem lokalen Rechner angezeigt. Dies muss explizit durch die Verwendung des --expose-env-vars-Flags erfolgen. Warum? Die Verbindung zur Datenbank in der Produktivumgebung ist ein gefährlicher Vorgang. Du kannst mit echten Daten herumpfuschen. Indem Du das Flag nutzt, bestätigst Du, dass Du dies wirklich tun möchtest.

Verbinde dich nun via symfony run psql wie bisher mit der remote PostgreSQL-Datenbank:

1
$ symfony run psql

Wenn du fertig bist, vergiss nicht, den Tunnel zu schließen:

1
$ symfony tunnel:close

Tipp

Um einige SQL-Abfragen auf der Production-Datenbank auszuführen, kannst Du auch den symfony sql-Befehl anstelle einer Shell verwenden.

Environment-Variablen bereitstellen

Docker Compose und SymfonyCloud arbeiten dank Environment-Variablen nahtlos mit Symfony zusammen.

Überprüfe alle Environment-Variablen, die durch symfony bereitgestellt werden, indem Du symfony var:export ausführst:

1
2
3
4
5
6
7
8
$ symfony var:export

PGHOST=127.0.0.1
PGPORT=32781
PGDATABASE=main
PGUSER=main
PGPASSWORD=main
# ...

Die PG* Environment-Variablen werden vom psql Dienstprogramm gelesen. Was ist mit den anderen?

Wenn ein Tunnel zu SymfonyCloud mit gesetztem --expose-env-vars-Flag geöffnet ist, gibt der var:export-Befehl die Environment-Variablen in der SymfonyCloud zurück:

1
2
3
$ symfony tunnel:open --expose-env-vars
$ symfony var:export
$ symfony tunnel:close

  • « Previous Schritt 6: Einen Controller erstellen
  • Next » Schritt 8: Die Datenstruktur beschreiben

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