Tutorial: Erstellen von Apps mit mehreren Containern mit MySQL und Docker Compose

In diesem Tutorial erfahren Sie. wie Sie Apps mit mehreren Containern erstellen. Dieses Tutorial baut auf den Tutorials für die ersten Schritte auf: Erste Schritte mit Docker und Visual Studio Code. In diesem erweiterten Tutorial aktualisieren Sie Ihre Anwendung so, dass sie wie in dieser Abbildung gezeigt funktioniert, und lernen Folgendes:

  • Starten von MySQL.
  • Ausführen der App mit MySQL.
  • Erstellen der Compose-Datei.
  • Ausführen des Anwendungsstapels.

Diagram shows two containers labeled Todo App and MySQL connected with a line.

Durch die Verwendung mehrerer Container können Sie Container für spezielle Aufgaben vorsehen. Jeder Container sollte eine Aufgabe haben und diese erfolgreich ausführen.

Dies sind einige Gründe für die Verwendung von Apps mit mehreren Containern:

  • Trennen Sie Container, um APIs und Front-Ends anders zu verwalten als Datenbanken.
  • Container ermöglichen das Verwalten und Aktualisieren von Versionen in Isolation.
  • Obwohl Sie möglicherweise einen Container lokal für die Datenbank verwenden, sollten Sie in der Produktion einen verwalteten Dienst für die Datenbank nutzen.
  • Zum Ausführen mehrerer Prozesse ist ein Prozess-Manager erforderlich, durch den das Starten/Herunterfahren von Containern komplexer wird.

Voraussetzungen

Dieses Tutorial setzt die Reihe von Tutorials fort, die mit Erstellen einer Container-App begonnen hat. Beginnen Sie mit diesem Tutorial, da dies die Voraussetzungen enthält. Führen Sie dann das Tutorial Persistentes Speichern von Daten in Ihrer App aus.

Sie benötigen außerdem folgende Elemente:

  • Docker Compose.

    Docker Desktop für Windows oder Mac enthält Docker Compose. Führen Sie diesen Befehl aus, um dies zu überprüfen:

    docker-compose version
    

    Wenn Sie das Linux-Betriebssystem verwenden, installieren Sie Docker Compose.

Wie in den vorherigen Tutorials können Sie die meisten Aufgaben über die VS Code-Ansicht EXPLORER oder die DOCKER-Ansicht ausführen. Sie können Terminal>Neues Terminal auswählen, um ein Befehlszeilenfenster in VS Code zu öffnen. Sie können Befehle auch in einem Bash-Fenster ausführen. Sofern nicht anders angegeben, kann jeder Befehl mit der Bezeichnung Bash in einem Bash-Fenster oder im VS Code-Terminal ausgeführt werden.

Starten Sie MySQL.

Container werden standardmäßig isoliert ausgeführt. Sie wissen nichts über andere Prozesse oder Container auf demselben Computer. Damit ein Container mit einem anderen Container kommunizieren kann, verwenden Sie das Netzwerk.

Wenn sich zwei Container im gleichen Netzwerk befinden, können sie miteinander kommunizieren. Wenn dies nicht der Fall ist, ist das eben nicht möglich.

Es gibt zwei Möglichkeiten, einen Container in einem Netzwerk zu platzieren: Entweder Sie weisen ihn beim Start zu, oder Sie verbinden ihn mit einem vorhandenen Container. In diesem Beispiel erstellen Sie zuerst das Netzwerk und fügen dann den MySQL-Container beim Start an.

  1. Erstellen Sie das Netzwerk mit diesem Befehl.

    docker network create todo-app
    
  2. Starten Sie einen MySQL-Container, und fügen Sie ihn dem Netzwerk an.

    docker run -d 
        --network todo-app --network-alias mysql 
        -v todo-mysql-data:/var/lib/mysql 
        -e MYSQL_ROOT_PASSWORD=<your-password> 
        -e MYSQL_DATABASE=todos 
        mysql:5.7
    

    Dieser Befehl definiert auch Umgebungsvariablen. Weitere Informationen finden Sie unter MySQL Docker Hub-Liste.

    Der Befehl gibt einen Netzwerkalias an: mysql.

  3. Verwenden Sie den Befehl docker ps, um Ihre Container-ID abzurufen.

  4. Stellen Sie eine Verbindung mit der Datenbank her, um zu bestätigen, dass die Datenbank aktiv ist und ausgeführt wird.

    docker exec -it <mysql-container-id> mysql -p
    

    Geben Sie das Kennwort ein, das Sie oben verwendet haben, als Sie zur Eingabe aufgefordert wurden.

  5. In der MySQL-Shell werden die Datenbanken aufgelistet. Überprüfen Sie, ob die Datenbank todos angezeigt wird.

    SHOW DATABASES;
    

    Die folgende Ausgabe wird angezeigt.

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. Geben Sie exit ein, wenn Sie wieder zur Terminaleingabeaufforderung zurückkehren möchten.

Ausführen der App mit MySQL

Die Todo-App unterstützt das Festlegen von Umgebungsvariablen zum Angeben von MySQL-Verbindungseinstellungen.

  • MYSQL_HOST: Der Hostname für den MySQL-Server.
  • MYSQL_USER: Der für die Verbindung zu verwendende Benutzername.
  • MYSQL_PASSWORD: Das für die Verbindung zu verwendende Kennwort.
  • MYSQL_DB: Die Datenbank, die nach dem Herstellen der Verbindung verwendet werden soll.

Warnung

Die Verwendung von Umgebungsvariablen zum Festlegen von Verbindungseinstellungen ist für die Entwicklung akzeptabel. Diese Vorgehensweise wird für die Ausführung von Anwendungen in der Produktion nicht empfohlen. Weitere Informationen hierzu finden Sie unter Warum Umgebungsvariablen nicht für geheime Daten verwendet werden sollten.

Ein sicherer Mechanismus ist die Verwendung der vom Containerorchestrierungsframework bereitgestellten Geheimnisunterstützung. In den meisten Fällen werden diese Geheimnisse als Dateien im laufenden Container bereitgestellt.

Mit diesem Verfahren wird Ihre App gestartet und dieser Container mit Ihrem MySQL-Container verbunden.

  1. Verwenden Sie den folgenden Befehl „docker run“. Er gibt die oben genannten Umgebungsvariablen an.

    docker run -dp 3000:3000 
      -w /app -v ${PWD}:/app 
      --network todo-app 
      -e MYSQL_HOST=mysql 
      -e MYSQL_USER=root 
      -e MYSQL_PASSWORD=<your-password> 
      -e MYSQL_DB=todos 
      node:20-alpine 
      sh -c "yarn install && yarn run dev"
    
  2. Klicken Sie in VS Code in der Docker-Ansicht mit der rechten Maustaste auf den App-Container, und wählen Sie Protokolle anzeigen aus. Verwenden Sie den Befehl docker logs, um die Protokolle über die Befehlszeile anzuzeigen.

    Das Ergebnis enthält eine Zeile, die angibt, dass die App mit der MySQL-Datenbank verbunden ist.

    # Previous log messages omitted
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Connected to mysql db at host mysql
    Listening on port 3000
    
  3. Geben Sie http://localhost:3000 in Ihrem Browser ein. Fügen Sie Ihrer Aufgabenliste einige Elemente hinzu.

  4. Stellen Sie wie im vorherigen Abschnitt eine Verbindung mit der MySQL-Datenbank her. Führen Sie diesen Befehl aus, um zu überprüfen, ob die Elemente in die Datenbank geschrieben werden.

    docker exec -ti <mysql-container-id> mysql -p todos
    

    Führen Sie in der MySQL-Shell die folgenden Befehle aus.

    use todos;
    select * from todo_items;
    

    Das Ergebnis sieht wie in der folgenden Ausgabe aus.

    +--------------------------------------+--------------------+-----------+
    | id                                   | name               | completed |
    +--------------------------------------+--------------------+-----------+
    | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
    | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
    +--------------------------------------+--------------------+-----------+
    

An diesem Punkt verfügen Sie über eine Anwendung, die Daten in einer externen Datenbank speichert. Diese Datenbank wird in einem separaten Container ausgeführt. Sie haben mehr über Containernetzwerke erfahren.

Erstellen einer Docker Compose-Datei

Docker Compose unterstützt Sie beim Definieren und Freigeben von Anwendungen mit mehreren Containern. Mit Docker Compose können Sie eine Datei erstellen, um die Dienste zu definieren. Mit einem einzelnen Befehl können Sie alles einrichten oder bereinigen.

Sie können Ihren Anwendungsstapel in einer Datei definieren und diese Datei im Stamm Ihres Projektrepositorys unter der Versionskontrolle speichern. Dieser Ansatz ermöglicht es anderen Benutzern, an Ihrem Projekt mitzuwirken. Sie müssen nur Ihr Repository klonen.

  1. Erstellen Sie im Stammverzeichnis des App-Projekts eine Datei namens docker-compose.yml.

  2. In der Compose-Datei beginnen Sie mit dem Definieren der Schemaversion.

    version: "3.7"
    

    In den meisten Fällen empfiehlt es sich, die neueste unterstützte Version zu verwenden. Aktuelle Schemaversionen und eine Kompatibilitätsmatrix finden Sie unter Compose-Datei.

  3. Definieren Sie die Dienste oder Container, die Sie als Teil Ihrer Anwendung ausführen möchten.

    version: "3.7"
    
    services:
    

    Tipp

    Einzüge sind in YML-Dateien von Bedeutung. Wenn die Bearbeitung in VS Code erfolgt, weist IntelliSense auf Fehler hin.

  4. Hier ist der Befehl, den Sie für Ihren App-Container verwendet haben. Sie fügen diese Informationen ihrer YML-Datei hinzu.

    docker run -dp 3000:3000 
      -w /app -v ${PWD}:/app 
      --network todo-app 
      -e MYSQL_HOST=mysql 
      -e MYSQL_USER=root 
      -e MYSQL_PASSWORD=<your-password> 
      -e MYSQL_DB=todos 
      node:20-alpine 
      sh -c "yarn install && yarn run dev"
    

    Definieren Sie den Diensteintrag und das Image für den Container.

    version: "3.7"
    
    services:
      app:
        image: node:20-alpine
    

    Sie können einen beliebigen Namen für den Dienst auswählen. Der Name wird automatisch zu einem Netzwerkalias, der beim Definieren des MySQL-Diensts nützlich ist.

  5. Fügen Sie den Befehl hinzu.

    version: "3.7"
    
    services:
      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
    
  6. Geben Sie die Ports für den Dienst an, die -p 3000:3000 im Befehl oben entsprechen.

    version: "3.7"
    
    services:
      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  7. Angeben des Arbeitsverzeichnisses und der Volumezuordnung

    version: "3.7"
    
    services:
      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    

    In Docker Compose-Volumedefinitionen können Sie relative Pfade aus dem aktuellen Verzeichnis verwenden.

  8. Geben Sie die Umgebungsvariablendefinitionen an.

    version: "3.7"
    
    services:
      app:
        image: node:20-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    
  9. Fügen Sie die Definitionen für den MySQL-Dienst hinzu. Dies ist der Befehl, den Sie oben verwendet haben:

    docker run -d 
      --network todo-app --network-alias mysql 
      -v todo-mysql-data:/var/lib/mysql 
      -e MYSQL_ROOT_PASSWORD=<your-password> 
      -e MYSQL_DATABASE=todos 
      mysql:5.7
    

    Definieren Sie den neuen Dienst, und nennen Sie ihn mysql. Fügen Sie den Text nach der app-Definition auf der gleichen Einzugsebene hinzu.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
    

    Der Dienst ruft automatisch den Netzwerkalias ab. Geben Sie das zu verwendende Image an.

  10. Definieren Sie die Volumezuordnung.

    Geben Sie das Volume mit einem volumes:-Abschnitt auf der gleichen Ebene wie services: an. Geben Sie die Volumezuordnung unter dem Image an.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
    volumes:
      todo-mysql-data:
    
  11. Geben Sie die Umgebungsvariablen an.

    version: "3.7"
    
    services:
      app:
        # The app service definition
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:
    

An diesem Punkt sieht die vollständige Datei docker-compose.yml wie folgt aus:

version: "3.7"

services:
  app:
    image: node:20-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: <your-password>
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: <your-password>
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

Ausführen des Anwendungsstapels

Nachdem Sie nun über die Datei docker-compose.yml verfügen, testen Sie sie.

  1. Stellen Sie sicher, dass keine anderen Kopien der App und der Datenbank ausgeführt werden. Klicken Sie in der Docker-Erweiterung mit der rechten Maustaste auf ggf. ausgeführte Container, und wählen Sie Entfernen aus. Verwenden Sie alternativ in der Befehlszeile den Befehl docker rm wie in den vorherigen Beispielen.

  2. Klicken Sie im VS Code-Explorer mit der rechten Maustaste auf docker-compose.yml, und wählen Sie Compose Up (Erstellen) aus. Verwenden Sie alternativ in der Befehlszeile den folgenden Docker-Befehl.

    docker-compose up -d
    

    Durch den -d-Parameter wird der Befehl im Hintergrund ausgeführt.

    Die Ausgabe sollte wie die folgenden Ergebnisse aussehen.

    [+] Building 0.0s (0/0)
    [+] Running 2/2
    ✔ Container app-app-1    Started                                                                                                       0.9s 
    ✔ Container app-mysql-1  Running
    

    Das Volume sowie ein Netzwerk wurde erstellt. Standardmäßig erstellt Docker Compose ein Netzwerk speziell für den Anwendungsstapel.

  3. Klicken Sie in der Docker-Erweiterung mit der rechten Maustaste auf den App-Container, und wählen Sie Protokolle anzeigen aus. Verwenden Sie den Befehl docker logs, um die Protokolle über die Befehlszeile anzuzeigen.

    mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
    mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    app_1    | Connected to mysql db at host mysql
    app_1    | Listening on port 3000
    

    Die Protokolle der einzelnen Dienste werden in einem einzigen Datenstrom kombiniert. Durch dieses Verhalten können Sie Timingprobleme beobachten.

    Der Dienstname wird am Anfang der Zeile angezeigt, um Meldungen unterscheiden zu können. Fügen Sie zum Anzeigen von Protokollen für einen bestimmten Dienst den Dienstnamen am Ende des logs-Befehls hinzu.

  4. An diesem Punkt sollten Sie Ihre App öffnen können. Geben Sie http://localhost:3000 in Ihrem Browser ein.

Wenn Sie mit diesen Containern fertig sind, können Sie sie einfach entfernen.

  • Klicken Sie im VS Code-Explorer mit der rechten Maustaste auf docker-compose.yml, und wählen Sie dann Compose Down (Entfernen) aus.
  • Führen Sie in der Befehlszeile docker-compose down aus.

Die Container werden beendet. Das Netzwerk wird entfernt.

Standardmäßig werden benannte Volumes in Ihrer Compose-Datei nicht entfernt. Wenn Sie die Volumes entfernen möchten, führen Sie docker-compose down --volumes aus.

Bereinigen von Ressourcen

Die Voraussetzungen, die Sie in dieser Tutorialreihe verwendet haben, können für zukünftige Docker-Entwicklung verwendet werden. Es gibt keinen Grund, Elemente zu löschen oder zu deinstallieren.

Nächste Schritte

In diesem Tutorial haben Sie mehr über Apps mit mehreren Containern und Docker Compose erfahren. Docker Compose vereinfacht das Definieren und Freigeben von Anwendungen mit mehreren Diensten erheblich.

Hier sind einige Ressourcen, die für Sie nützlich sein können: