Docker und Go: Vollständiger Leitfaden zur Containerisierung von Golang-Anwendungen
Die Containerisierung ist zum De-facto-Standard für die Bereitstellung moderner Anwendungen geworden. Die Sprache Go (Golang) ist ideal für Containerumgebungen: Ihre kompilierten Binärdateien benötigen keine Laufzeitumgebung, und statisches Linken ermöglicht minimale Docker-Images. In diesem Artikel werden wir den Prozess der Containerisierung von Go-Anwendungen vom Schreiben eines Dockerfiles bis zur Optimierung der endgültigen Image-Größe erläutern.
Warum Go und Docker ein ideales Paar sind
Go wird in eine einzige statische Binärdatei kompiliert, die nicht von Systembibliotheken abhängt. Das bedeutet, dass für die Ausführung einer Go-Anwendung in einem Container keine Go-Laufzeitumgebung, Interpreter oder zusätzliche Abhängigkeiten installiert werden müssen. Das Ergebnis:
- Minimale Image-Größe — oft unter 10-15 MB
- Schneller Start — Millisekunden statt Sekunden
- Hohe Sicherheit — weniger Komponenten = weniger Schwachstellen
- Einfaches Deployment — eine Binärdatei statt vieler Skripte und Bibliotheken
Betrachten wir dies am Beispiel eines einfachen HTTP-Servers in Go.
Schritt 1: Go-Anwendung erstellen
Zunächst schreiben wir eine einfache Webanwendung, die containerisiert werden soll. Erstellen Sie die Datei main.go:
package main
import ( "fmt" "log" "net/http" "os")
func main() { port := os.Getenv("PORT") if port == "" { port = "8080" }
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Привет из контейнера Go! 🐳") })
log.Printf("Сервер запущен на порту %s", port) log.Fatal(http.ListenAndServe(":"+port, nil))}Dies ist ein minimaler HTTP-Server, der auf dem in der Umgebungsvariable PORT angegebenen Port lauscht (standardmäßig 8080).
Schritt 2: Multi-Stage-Build
Um ein minimales Docker-Image zu erstellen, wird ein Multi-Stage-Build verwendet. Die erste Stufe kompiliert die Anwendung, die zweite erstellt das endgültige Image nur mit der Binärdatei. Erstellen Sie Dockerfile:
# Этап 1: Сборка приложенияFROM golang:1.22-alpine AS builder
WORKDIR /app
# Копируем go.mod и go.sum для кэширования зависимостейCOPY go.mod go.sum ./RUN go mod download
# Копируем исходный кодCOPY . .
# Собираем статический бинарный файлRUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .
# Этап 2: Финальный минимальный образFROM alpine:3.19
# Добавляем CA-сертификаты для HTTPSRUN apk --no-cache add ca-certificates
WORKDIR /root/
# Копируем бинарник из первого этапаCOPY --from=builder /app/server .
# Открываем портEXPOSE 8080
# Запускаем приложениеCMD ["./server"]Beachten Sie die wichtigsten Punkte:
golang:1.22-alpine— leichtgewichtiges Image zum BauenCGO_ENABLED=0— deaktiviert CGO für statisches Linkenalpine:3.19— minimales Linux-Image (~5 MB)ca-certificates— erforderlich, wenn die Anwendung HTTPS verwendet
Schritt 3: Container bauen und starten
Bauen Sie das Docker-Image und starten Sie den Container:
# Сборка образаdocker build -t go-hello:latest .
# Запуск контейнераdocker run -d -p 8080:8080 --name go-app go-hello:latest
# Проверкаcurl http://localhost:8080# Вывод: Привет из контейнера Go! 🐳Überprüfen Sie die Größe des erstellten Images:
docker images go-hello# REPOSITORY TAG IMAGE ID CREATED SIZE# go-hello latest abc123def456 10 seconds ago 14.2 MBNur 14,2 MB – das ist im Vergleich zu Node.js-Images (Hunderte MB) oder Python-Images (Dutzende MB) verschwindend gering.