Einführung
Pine & Path schickt seinen Besucherführer für Alder Ridge an ein anderes Besucherzentrum. Das aktuelle Image funktioniert, enthält neben der Anwendung aber auch den Go-Compiler, Quelldateien und Build-Reste. Liefere ein schlankes Laufzeit-Image, das weiterhin alle vier Wanderwege, Schwierigkeitsfilter, Detailseiten, lokale Grafiken und vollständige GPX-Routendownloads bereitstellt.
Du solltest bereits ein einfaches Docker-Image bauen und starten können sowie Dockerfile FROM, COPY und Portfreigaben kennen. Go-Programmierkenntnisse sind nicht erforderlich: Die vollständige Anwendung und alle Materialien werden bereitgestellt. Dieses Lab erklärt Kompilierung, Build-Stages, die Dateistruktur zur Laufzeit und die Shell-Syntax zum Schreiben von Dateien vor ihrer Verwendung. Park und Routendaten sind fiktive Unterrichtsmaterialien.
Docker, das Builder-Image und der bereitgestellte Referenzdienst sind vorbereitet. Nutze Workstation für Befehle, Reference Guide für das funktionierende Beispiel und Your Guide für deine Lieferung. Dieses Lab ist unabhängig von der Challenge. Plane etwa 60 Minuten einschließlich Lesen, Builds und gewöhnlicher Fehler ein; dies ist eine Schätzung des Autors.
Das funktionierende Ausgangs-Image bauen
In diesem Schritt stellst du fest, was ein vollständiger Führer bietet, und baust dann das bereitgestellte Ausgangs-Image. Beginne in Reference Guide. Dort siehst du vier Wanderwege. Wähle Easy, öffne Cedar Loop, lies Distanz und Höhenanstieg und nutze Download GPX. GPX ist XML mit einem benannten Track und geografischen Punkten; dieser Download ist eine echte Routendatei. Wähle Back to trails, dann Moderate, und öffne Ridge Path. Kehre zur Ansicht aller Wege zurück. Achte neben dem Text auch auf Stylesheet und schematische Karte: Auch sie sind Laufzeitressourcen.

Wechsle zu Workstation, das in /home/labex/project/trail-guide startet. pwd zeigt das aktuelle Verzeichnis und ls dessen Einträge an. Falls du das Projekt verlässt, wechselt das folgende cd wieder dorthin:
cd /home/labex/project/trail-guide
ls
Die bereitgestellte Struktur:
| Quellpfad | Zweck zur Laufzeit |
|---|---|
app/main.go |
Zu kompilierendes Go-Programm, dessen Quelle zur Laufzeit nicht benötigt wird |
content/trails.json |
Alle vier Wege und ihre Beziehungen |
content/routes/ |
Die vier GPX-Downloads |
public/ |
Stylesheet und originale schematische Grafiken |
author-notes/, build-cache/ |
Entwürfe und Reste, keine Laufzeitressourcen |
Lasse diese Materialien und den Referenzdienst unverändert. Du bearbeitest Dockerfile, ergänzt .dockerignore und erstellst Images und Container für den Kurs. Dockerfile.incomplete ist ein vorbereitetes Fehlerbeispiel für den nächsten Schritt.
cat zeigt eine Textdatei an. Lies das vorhandene Dockerfile:
cat Dockerfile
Es beginnt mit dk02-go-builder:1, einem vorbereiteten Image mit Go-Compiler. WORKDIR /guide legt das Arbeitsverzeichnis im Image fest. COPY . . kopiert den aktuellen Build-Kontext dorthin, einschließlich Dateien, die die fertige Anwendung nicht benötigt. Das abschließende ENTRYPOINT ist ein JSON-Array, das das kompilierte Programm direkt startet.
Der Build-Befehl setzt für diesen Befehl CGO_ENABLED=0. Da dieses Go-Beispiel ausschließlich die Go-Standardbibliothek verwendet, benötigt es damit keine C-Bibliotheken. go build kompiliert das bereitgestellte Programm; -trimpath entfernt lokale Quellverzeichnisdetails aus der ausführbaren Datei, und -o /guide/guide benennt sie. Dadurch eignet sich dieses konkrete Programm für eine leere Laufzeitbasis. Andere Programme brauchen möglicherweise gemeinsam genutzte Bibliotheken, Zertifikate oder weitere Daten; eine leere Basis ist keine universelle Lösung.
Lies zunächst die Compiler-Version. docker run --rm erstellt einen temporären Container und entfernt ihn nach Befehlsende. Die Wörter nach dem Image-Namen wählen den auszuführenden Befehl aus:
docker run --rm dk02-go-builder:1 go version
Die Ausgabe nennt Go 1.26 unter Linux. Hier läuft der Compiler in einem Container, nicht auf Workstation.
Baue das Ausgangs-Image. docker build liest das Dockerfile; -t gibt dem Ergebnis einen Tag, und der abschließende . wählt das aktuelle Verzeichnis als Build-Kontext:
docker build -t trail-guide:sample .
Warte auf den erfolgreichen Build-Abschluss. Der Tag bezeichnet ein Image, keinen laufenden Container. Um seine Größe in Byte zu sehen, liest docker image inspect die Metadaten und --format wählt ein Feld aus. Einfache Anführungszeichen übergeben die Vorlage unverändert:
docker image inspect trail-guide:sample --format '{{.Size}}'
Die Zahl hängt vom vorbereiteten Compiler-Image ab. Das Ausgangs-Image funktioniert, enthält aber weiterhin Compiler und Quellen. Eine geringe Größe allein beweist nicht, dass der Ersatz vollständig ist.
Build-Dateien von Laufzeitdateien trennen
In diesem Schritt baust du das Programm in einer Stage und lieferst in einer anderen nur seine ausführbare Datei und Laufzeitressourcen. Beginne in Workstation im selben Projektverzeichnis. Eine Stage beginnt mit einer FROM-Anweisung. Mit dem Namen AS build kann ein späteres COPY --from=build ein Ergebnis übernehmen, ohne den Compiler oder frühere Dateisystem-Layer zu erben.
Untersuche zunächst eine tatsächlich unvollständige Lieferung. Das bereitgestellte Dockerfile.incomplete kompiliert das Programm und kopiert die öffentlichen Grafiken, lässt aber die Wegedaten aus:
cat Dockerfile.incomplete
Die Option -f wählt dieses alternative Dockerfile:
docker build -f Dockerfile.incomplete -t trail-guide:incomplete .
Der Build gelingt, weil die Kompilierung die Wegesammlung nicht liest. Der folgende Start soll ausdrücklich mit Exit-Status 1 fehlschlagen:
docker run --rm trail-guide:incomplete
Lies den Fehler: open content/trails.json: no such file or directory. Die ausführbare Datei ist vorhanden, aber ihre Laufzeitdaten fehlen. Ein erfolgreicher Build und eine vollständige Anwendung sind unterschiedliche Ergebnisse. Der fehlgeschlagene temporäre Container wurde entfernt. Korrigiere das normale Dockerfile, statt diesen Container zu reparieren oder die Anwendung zu ändern.
Ein Here-Dokument speichert einen vollständigen Textblock. Unten liefert cat die Zeilen, > schreibt Dockerfile, und <<'DOCKERFILE' kennzeichnet einen wörtlichen Block, der bei einer Zeile mit ausschließlich DOCKERFILE endet. Die Anführungszeichen am Anfang verhindern Shell-Ersetzungen beim Speichern. Ersetze nur das bearbeitbare Dockerfile:
cat > Dockerfile <<'DOCKERFILE'
FROM dk02-go-builder:1 AS build
WORKDIR /src
COPY app/main.go ./main.go
RUN CGO_ENABLED=0 go build -trimpath -o /out/guide main.go
FROM scratch
WORKDIR /guide
COPY --from=build /out/guide ./guide
COPY content/ ./content/
COPY public/ ./public/
ENTRYPOINT ["/guide/guide"]
DOCKERFILE
Verfolge die Dateien: Die erste Stage kompiliert die Quelle nach /out/guide. Das zweite FROM beginnt mit scratch, Dockers leerer Dateisystembasis, ohne die erste Stage zu erben. Die ausführbare Datei wird zu /guide/guide; Wegedaten und GPX-Dateien behalten ihre content-Struktur, Stile und Grafiken ihre public-Struktur. Das Programm liest diese relativen Pfade aus seinem Arbeitsverzeichnis. Deshalb reichte es nicht aus, nur die ausführbare Datei zu kopieren.
Das endgültige Image enthält weder Shell noch Compiler. Das ist hier beabsichtigt. Untersuche die Anwendung, statt eine Shell darin starten zu wollen.
Der Build-Kontext ist ein eigener Aspekt. .dockerignore schließt passende Kontextpfade aus, bevor sie an den Builder gesendet werden. Der führende Punkt macht den Dateinamen verborgen. Diese Regeln lassen Entwürfe und veralteten Cache weg, ohne Anwendung oder Laufzeitressourcen auszuschließen:
cat > .dockerignore <<'IGNORE'
author-notes/
build-cache/
IGNORE
Das Dockerfile mit zwei Stages wählt Laufzeitdateien ausdrücklich aus; die Ignore-Datei verhindert zusätzlich, dass unnötiges Material gesendet wird. Eine Kontextdatei auszuschließen entfernt keine Bytes, die bereits in geerbten Layern liegen. Die separate Laufzeit-Stage lässt die Build-Layer zurück.
Baue das Liefer-Image:
docker build -t trail-guide:lean .
docker image inspect trail-guide:lean --format '{{.Size}}'
Vergleiche die Zahl mit dem Ausgangs-Image. Das sinnvolle Ergebnis ist eine kleinere Laufzeitumgebung mit vollständigem Führer, nicht die kleinstmögliche Zahl. Wenn ein COPY fehlschlägt, lies den fehlenden Quellpfad und vergleiche ihn mit der Strukturtabelle und dem aktuellen Verzeichnis. Korrigiere Dockerfile oder Ignore-Regel und baue erneut. Erstelle keine Ersatzdaten und mounte nicht den Quellordner, um ein unvollständiges Image zu verbergen.
Den gelieferten Führer starten und neu erstellen
In diesem Schritt startest du das Image unabhängig vom Quellordner und nutzt den vollständigen Führer. Beginne in Workstation. Das Programm lauscht auf Container-Port 8080. Die Freigabe 8090:8080 macht es auf Port 8090 von Workstation erreichbar, den Your Guide anzeigt. -d lässt den Server im Hintergrund laufen; --name benennt diesen Kurscontainer. Ergänze keine Mounts: Das Image muss seine Ressourcen selbst enthalten.
docker run -d --name trail-guide -p 8090:8080 trail-guide:lean
Die Ausgabe ist eine Container-ID. Dieser Container läuft weiter, um den Führer bereitzustellen. docker logs liest die Programmausgabe; --tail 5 begrenzt sie auf die letzten fünf Zeilen:
docker logs --tail 5 trail-guide
Erwarte Guide listening on :8080, also den Container-Port statt des freigegebenen Host-Ports. Falls der Containername von einem früheren Versuch belegt ist, nutze den unten stehenden, auf diesen Kurs begrenzten Löschbefehl und wiederhole den Start. Bei einem Fehler wegen fehlender Ressourcen musst du zunächst das Dockerfile korrigieren und neu bauen.
Wechsle zu Your Guide und lade neu. Alle vier Wege sollten erscheinen. Wähle Easy: Nur Cedar Loop und River Walk erscheinen. Öffne Cedar Loop, prüfe Daten und Karte und lade seine GPX-Datei herunter. Nutze Back to trails, wähle Moderate, öffne Ridge Path und lade auch diese Route herunter. Kehre zu allen Wegen zurück. Lokale Grafiken und Stile müssen laden, und die Tracks müssen zu den ausgewählten Wegen gehören. Reference Guide bleibt unabhängig verfügbar.

Zeige nun einen Ersatzcontainer aus demselben Image. Wechsle zu Workstation. docker rm -f stoppt und entfernt nur den genannten Kurscontainer; das Image bleibt erhalten. Lasse dk02-reference laufen:
docker rm -f trail-guide
Erstelle eine neue Instanz ohne Mounts:
docker run -d --name trail-guide -p 8090:8080 trail-guide:lean
Wechsle zu Your Guide, lade neu und wiederhole die Besuche und Downloads für Easy/Cedar Loop und Moderate/Ridge Path. Dieser neue Container hat den Quellordner von Workstation nie erhalten. Seine Laufzeitressourcen stammen aus dem Image.
Lasse den Container laufen. Nach späteren Dockerfile-Änderungen aktualisiert das Neubauen eines Tags keinen vorhandenen Container; entferne und erstelle nur deinen Kurscontainer neu, um das neue Image zu starten. Ein gestoppter Dienst oder Verbindungsfehler unterscheidet sich von der anwendungseigenen Seite Trail not found für eine unbekannte Route.
Zusammenfassung
Du hast eine Compiler-Stage von einer leeren Laufzeit-Stage getrennt, die tatsächlich benötigten Anwendungsressourcen kopiert und Entwürfe aus dem Build-Kontext ausgeschlossen. Dein schlankes Image stellt die vollständige Sammlung, Filter, Details, Grafiken und GPX-Downloads ohne Mounts von Workstation bereit. Durch das Neuerstellen des Containers hast du gezeigt, dass das Image eine wiederverwendbare Lieferung ist und kein Prozess, der sich den Quellordner ausleiht.



