Zum Inhalt springen

Aufgabe 10 - Compose mit Anwendung und Datenbank

Zu Zen-Modus wechseln

Sie beschreiben Ihr Projekt als Verbund aus mehreren Diensten: Anwendung und Datenbank, mit internem Netz, Volume und Healthcheck (siehe Kapitel Auslieferung mit Containern). Zwei Fehler dieser Übung fallen erst später auf und dann teuer: eine Datenbank ohne Volume und ein veröffentlichter Datenbankport. Beide führen Sie hier absichtlich herbei, damit Sie sie einmal gesehen haben.

  • Kapitel Auslieferung mit Containern, Abschnitt Compose: mehrere Dienste.
  • Kapitel Server aufsetzen und härten, Abschnitt Firewall mit der Docker-Ausnahme.
  • Das Image aus Aufgabe 09, Docker mit Compose und Ihren Server aus Aufgabe 08.
  • Sie beschreiben mehrere Dienste mit Compose, mit internem Netz, Volume und Healthcheck.
  • Sie entscheiden, welche Konfiguration ins Image, welche in die Umgebung und welche in die Dokumentation gehört.
  • Sie erkennen, dass Docker die Firewall umgeht, und ziehen die richtige Konsequenz daraus.
  • Reproduktion: eine Compose-Datei nach Vorlage schreiben und den Verbund starten (Teil A).
  • Reorganisation und Transfer: Volume, Healthcheck und Umgebungswerte auf das eigene Projekt übertragen (Teil B).
  • Reflexion, Problemlösung und Urteilsbildung: Datenverlust und offene Ports herbeiführen, erklären und abstellen (Teil C).

Die Übung ist auf etwa zwei Stunden ausgelegt.

  1. Schreiben Sie eine docker-compose.yml mit zwei Diensten: app mit Ihrem Image aus Aufgabe 09 und db mit PostgreSQL. Starten Sie den Verbund mit docker compose up -d.

  2. Prüfen Sie mit docker compose ps und docker compose logs -f, ob beide Dienste laufen. Notieren Sie aus den Logs die Zeile, an der Sie erkennen, dass die Datenbank bereit ist.

  3. Weisen Sie nach, dass die Anwendung die Datenbank über den Dienstnamen erreicht und nicht über eine IP-Adresse. Rufen Sie dazu docker compose exec app getent hosts db auf. Erklären Sie in zwei Sätzen, woher dieser Name kommt.

  4. Legen Sie ein eigenes Netzwerk namens internal an und hängen Sie beide Dienste hinein. Rufen Sie docker network inspect auf und notieren Sie, welche Container darin liegen.

  1. Legen Sie in der Datenbank eine Tabelle mit ein paar Zeilen an. Führen Sie docker compose down und danach docker compose up -d aus. Sehen Sie nach, ob die Daten noch da sind, und notieren Sie das Ergebnis.

  2. Ergänzen Sie ein Volume für das Datenverzeichnis der Datenbank unter /var/lib/postgresql/data und wiederholen Sie den Versuch aus Punkt 1. Notieren Sie den Unterschied und erklären Sie ihn in zwei bis drei Sätzen.

  3. Ergänzen Sie einen Healthcheck für die Datenbank mit pg_isready und lassen Sie die Anwendung mit depends_on und condition: service_healthy darauf warten.

  4. Weisen Sie die Wirkung nach. Starten Sie den Verbund einmal ohne und einmal mit Healthcheck neu und sehen Sie jeweils in den Logs der Anwendung nach, ob in den ersten Sekunden Verbindungsfehler auftreten. Notieren Sie beide Ergebnisse.

  5. Erklären Sie in drei bis vier Sätzen den Unterschied zwischen „der Container ist gestartet” und „der Dienst darin nimmt Anfragen an”. Beantworten Sie dabei, welche der beiden Zusicherungen depends_on allein gibt.

  6. Nehmen Sie das Passwort der Datenbank aus der Compose-Datei heraus und beziehen Sie es als ${DB_PASSWORD} aus der Umgebung. Rufen Sie docker compose config auf und notieren Sie, welcher Wert dort tatsächlich eingesetzt wird.

  7. Prüfen Sie mit git status und einem Blick in .gitignore, dass docker-compose.yml im Repository liegt und .env nicht.

  8. Ergänzen Sie restart: unless-stopped für beide Dienste. Erklären Sie in zwei Sätzen, wovor diese Einstellung schützt und wovor nicht.

  1. Ordnen Sie jede Konfigurationsangabe Ihres Projekts einer von drei Ablagen zu: Image, Umgebung oder Dokumentation. Begründen Sie jede Zuordnung in einem halben Satz und legen Sie die Tabelle in docs/architektur.md ab.

  2. Führen Sie den Datenverlust vor. Entfernen Sie das Volume aus der Compose-Datei, legen Sie Daten an, führen Sie docker compose down -v aus und starten Sie neu. Halten Sie das Ergebnis fest.

  3. Beschreiben Sie in vier bis fünf Sätzen, wann dieser Fehler in einem echten Projekt auffällt. Gehen Sie davon aus, dass die Anwendung im Oktober in Betrieb geht und im Dezember zum ersten Mal neu ausgeliefert wird. Stellen Sie das Volume danach wieder her.

  4. Führen Sie die Firewall-Ausnahme vor. Veröffentlichen Sie den Datenbankport auf Ihrem Server mit ports: "5432:5432" und einem Wegwerf-Passwort. Rufen Sie sudo ufw status verbose auf, das weiterhin „deny” anzeigt, und prüfen Sie danach die Erreichbarkeit von einem zweiten Rechner aus. Notieren Sie beide Ergebnisse nebeneinander.

  5. Erklären Sie in fünf bis sechs Sätzen, warum die Firewall hier nicht greift. Gehen Sie darauf ein, in welcher Reihenfolge Docker und ufw ihre Regeln in iptables eintragen.

  6. Nennen Sie die beiden Gegenmaßnahmen aus dem Kapitel und setzen Sie die passende um: entweder den Port gar nicht veröffentlichen oder ihn an 127.0.0.1 binden. Ändern Sie danach das Wegwerf-Passwort.

  7. Richten Sie den richtigen Weg ein, um lokal mit einem Werkzeug auf die Datenbank zu sehen: einen SSH-Tunnel mit ssh -L 5432:localhost:5432 <server>. Notieren Sie den Befehl und weisen Sie mit einer Verbindung nach, dass er funktioniert.

  8. Ergänzen Sie docs/haertung.md um einen Abschnitt Container und Ports. Darin steht, welche Ports Ihr Verbund veröffentlicht, welche nicht, und mit welchem Befehl Sie das geprüft haben.

  1. Woher kennt die Anwendung den Namen db, und warum steht dort keine IP-Adresse?
  2. Warum überlebt eine Datenbank ohne Volume das nächste Deployment nicht?
  3. Was sichert depends_on zu, und was sichert erst ein Healthcheck zu?
  4. Warum gehört docker-compose.yml ins Repository und .env nicht?
  5. Was bewirkt restart: unless-stopped, und wovor schützt es nicht?
  6. Warum ist ein mit ports: veröffentlichter Datenbankport aus dem Internet erreichbar, obwohl ufw ihn verbietet?
  7. Was ist der richtige Weg, um von außen mit einem Werkzeug auf die Datenbank zu sehen?

docker-compose.yml liegt im Repository: Anwendung und Datenbank im internen Netz, mit Volume und Healthcheck, ohne veröffentlichte Datenbankports, das Passwort aus der Umgebung. Die Zuordnungstabelle steht in docs/architektur.md, der Abschnitt Container und Ports in docs/haertung.md. Die Versuchsergebnisse aus den Teilen B und C stehen in protokoll.md.