Aufgabe 09 - Vom lokalen Projekt zum Image
Aufgabe 09 - Vom lokalen Projekt zum Image
Abschnitt betitelt „Aufgabe 09 - Vom lokalen Projekt zum Image“Worum geht es?
Abschnitt betitelt „Worum geht es?“Sie schreiben das Dockerfile für Ihr Jahresprojekt und bauen daraus ein Image, das ohne root läuft und klein genug ist, um es bei jedem Deployment zu übertragen (siehe Kapitel Auslieferung mit Containern). Der Unterschied zwischen einem Image von 1,2 GB und einem von 180 MB ist keine Kosmetik. Dieses Image entsteht ab jetzt bei jedem Push.
Was Sie dafür brauchen
Abschnitt betitelt „Was Sie dafür brauchen“- Kapitel Auslieferung mit Containern, Abschnitte Warum überhaupt Container und Das eigene Dockerfile.
- Ihr Projekt aus Aufgabe 03 mit einer Anwendung, die lokal startet.
- Docker auf Ihrem eigenen Rechner.
Welche Kompetenzen Sie erwerben und zeigen
Abschnitt betitelt „Welche Kompetenzen Sie erwerben und zeigen“- Sie unterscheiden Image, Container und Volume und begründen, warum ein Container jederzeit ersetzbar sein muss.
- Sie schreiben ein mehrstufiges
Dockerfile, das ohnerootläuft und ein schlankes Laufzeit-Image erzeugt. - Sie erklären den Unterschied zwischen Bauzeit- und Laufzeitvariablen und ziehen die Folgen für Geheimnisse.
Pädagogische Einordnung
Abschnitt betitelt „Pädagogische Einordnung“- Reproduktion: die drei Begriffe unterscheiden und ein
Dockerfilenach Vorlage schreiben (Teil A). - Reorganisation und Transfer: die mehrstufige Bauweise auf das eigene Projekt übertragen und das Ergebnis messen (Teil B).
- Reflexion, Problemlösung und Urteilsbildung: Bauzeitpunkte einordnen und die Geheimnisfrage beurteilen (Teil C).
Arbeitsaufträge
Abschnitt betitelt „Arbeitsaufträge“Die Übung ist auf etwa zwei Stunden ausgelegt.
Teil A - Image, Container, Volume
Abschnitt betitelt „Teil A - Image, Container, Volume“-
Starten Sie einen Container aus einem fertigen Image mit
docker run -it --rm alpine sh. Legen Sie darin eine Datei an, beenden Sie den Container und starten Sie einen neuen aus demselben Image. Notieren Sie, ob die Datei noch da ist, und erklären Sie das Ergebnis in zwei Sätzen. -
Wiederholen Sie den Versuch, diesmal mit einem Volume. Legen Sie es mit
docker volume create uebungan und hängen Sie es beim Start mit-v uebung:/datenein. Legen Sie die Datei unter/datenan und notieren Sie den Unterschied zu Punkt 1. -
Erklären Sie in je zwei Sätzen, was ein Image ist, was ein Container und was ein Volume. Nennen Sie zu jedem der drei Begriffe einen Bestandteil Ihres eigenen Projekts, der später dorthin gehört.
-
Nennen Sie drei Dinge aus Ihrem Projekt, die beim nächsten Deployment verschwinden würden, wenn Sie sie im Container ablegen statt in einem Volume. Hochgeladene Bilder, eine SQLite-Datei neben der Anwendung und ein von Hand nachinstalliertes Paket sind die üblichen Kandidaten.
Teil B - Das Dockerfile
Abschnitt betitelt „Teil B - Das Dockerfile“-
Schreiben Sie ein einstufiges
Dockerfilefür Ihr Projekt mit Basis-Image, Abhängigkeiten, Quellcode, Build und Startbefehl. Bauen Sie es und notieren Sie die Größe ausdocker images. -
Schreiben Sie daraus ein mehrstufiges
Dockerfilemit den drei Stufendeps,buildundruntime. In die letzte Stufe kommt nur, was zur Laufzeit gebraucht wird. -
Bauen Sie erneut und notieren Sie die neue Größe. Stellen Sie beide Werte gegenüber und rechnen Sie die Ersparnis in Prozent aus.
-
Ergänzen Sie einen eigenen Benutzer, sodass der Prozess im Container nicht als
rootläuft. Weisen Sie das Ergebnis mitdocker run --rm <image> idnach und notieren Sie die Ausgabe. -
Legen Sie eine
.dockerignorean. Prüfen Sie danach mitdocker run --rm <image> ls -la, dass weder.gitnoch.envnochnode_modulesim Image gelandet sind, und notieren Sie das Ergebnis. -
Starten Sie das Image lokal mit
docker run --rm -p 3000:3000 --env-file .env <image>und rufen Sie die Anwendung im Browser auf. Notieren Sie, welche Variablen gefehlt haben, bis es lief. -
Sehen Sie sich mit
docker history <image>an, welche Schicht wie viel zur Größe beiträgt. Nennen Sie die drei größten Schichten und zu jeder einen Weg, sie zu verkleinern. Setzen Sie eine dieser Maßnahmen um und stellen Sie die Größe vorher und nachher gegenüber.
Teil C - Bauzeit, Laufzeit und Geheimnisse
Abschnitt betitelt „Teil C - Bauzeit, Laufzeit und Geheimnisse“-
Ändern Sie eine einzige Zeile in Ihrem Quellcode und bauen Sie neu. Notieren Sie die Bauzeit und welche Schichten aus dem Cache kamen.
-
Verschieben Sie
COPY . .versuchsweise vor die Installation der Abhängigkeiten. Bauen Sie zweimal, ändern Sie zwischendurch wieder eine Zeile Quellcode, und notieren Sie die Bauzeit erneut. Stellen Sie beide Zeiten gegenüber und erklären Sie den Unterschied in drei bis vier Sätzen mit dem Schichtencache. Stellen Sie danach die richtige Reihenfolge wieder her. -
Legen Sie eine Tabelle Ihrer Umgebungsvariablen an mit den Spalten Name, Zweck, Bauzeit oder Laufzeit, Geheimnis?. Tragen Sie jede Variable ein, die Ihr Projekt kennt.
-
Belegen Sie den Unterschied praktisch. Setzen Sie eine Variable mit dem Präfix
NEXT_PUBLIC_und eine ohne, bauen Sie das Image und suchen Sie beide Werte im ausgelieferten JavaScript. Notieren Sie, welchen der beiden Sie finden. -
Beantworten Sie in drei bis vier Sätzen, warum ein Geheimnis niemals ein
NEXT_PUBLIC_-Präfix bekommen darf. Erklären Sie dabei, warum ein noch so gut abgesicherter Server daran nichts ändert. -
Bauen Sie versuchsweise ein Image, in dem
.envmitkopiert wird, also ohne den Eintrag in.dockerignore. Finden Sie den Wert im fertigen Image wieder, etwa mitdocker run --rm <image> cat .env. Beschreiben Sie in vier bis fünf Sätzen, warum ein Image kein sicherer Ort für Zugangsdaten ist. Gehen Sie darauf ein, was mit einem Image geschieht, das in einer Registry liegt oder weitergegeben wird. Löschen Sie das Image danach. -
Vervollständigen Sie
.env.examplemit allen Namen aus Ihrer Tabelle, weiterhin ohne echte Werte. -
Schreiben Sie einen Eintrag in
docs/entscheidungen.mdzum gewählten Basis-Image und zur Laufzeitstufe, mit den vier Abschnitten Entscheidung, Alternativen, Begründung und Folgen.
Wissenscheck
Abschnitt betitelt „Wissenscheck“- Was unterscheidet ein Image von einem Container, und was von einem Volume?
- Warum muss ein Container jederzeit ersetzbar sein, und welche Fehler folgen aus dem Gegenteil?
- Warum wird
package.jsonvor dem übrigen Quellcode kopiert? - Was bringt eine mehrstufige Bauweise, und was genau bleibt in der letzten Stufe zurück?
- Wann wird eine Variable mit
NEXT_PUBLIC_-Präfix gelesen, wann eine ohne, und was folgt daraus für Geheimnisse? - Wozu dient
.dockerignore, und welcher Eintrag darin ist der wichtigste? - Warum läuft der Prozess im Container unter einer eigenen Kennung und nicht als
root?
Dockerfile und .dockerignore liegen im Repository, das Image baut lokal und läuft ohne root. .env.example ist vollständig, der Eintrag zum Basis-Image steht in docs/entscheidungen.md. In protokoll.md stehen die Größenvergleiche aus Teil B, die Bauzeitmessungen aus Teil C, die Variablentabelle und das Ergebnis des Versuchs mit der mitkopierten .env.