
Wie man Go dockerisiert und deployed
Lukas MauserDieses Dockerfile kompiliert deine Go App zu einem einzelnen statischen Binary und liefert es dann auf einem winzigen Alpine-Image aus, sodass der finale Container nur ein paar Megabyte groß ist.
Falls du nur zum Kopieren und Einfügen hier bist, hier ist das fertige Dockerfile, das ein Image für deine Go App erstellt:
FROM golang:1.23-alpine AS build
WORKDIR /src
# Erst die Module runterladen, damit dieser Layer gecacht bleibt, wenn sich nur der Quellcode ändert
COPY go.mod go.sum ./
RUN go mod download
# Ein statisches Binary bauen
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .
FROM alpine:3.20 AS runtime
WORKDIR /app
# Zertifikate, damit das Binary ausgehende HTTPS-Calls machen kann
RUN apk add --no-cache ca-certificates
COPY --from=build /app/server .
EXPOSE 8080
CMD ["./server"]
Und hier ist die .dockerignore Datei:
.git
*.md
Dockerfile
.dockerignore
Um das Image zu bauen und auszuführen, nutze diese Befehle:
docker build -t go-app .
docker run -p 8080:8080 go-app
Nicht nur zum Kopieren und Einfügen hier? Dann lass uns durchgehen, was im Dockerfile passiert!
Das Setup
Für dieses Tutorial gehe ich davon aus, dass du eine Go App hast, die einen HTTP-Server startet, mit einer go.mod Datei im Root. Go kompiliert zu einem einzelnen self-contained Binary, was super zu Containern passt: die Build-Stage braucht die komplette Go-Toolchain, aber die Runtime-Stage braucht fast nichts.
Falls dein Projekt noch keine externen Dependencies hat, hat es eventuell keine go.sum Datei. In dem Fall lass sie einfach aus der COPY go.mod go.sum ./ Zeile weg.
Das Dockerfile
Die build Stage kompiliert das Binary:
- Basis-Image:
- Nutzt
golang:1.23-alpine, das den Go-Compiler und das Tooling auf einer kleinen Basis hat.
- Module-Caching:
- Kopiert erst
go.modundgo.sumund führtgo mod downloadaus. Das cacht deine Dependencies in einem eigenen Layer, damit sie nicht bei jeder Quellcode-Änderung neu runtergeladen werden.
- Build-Schritt:
- Führt
go buildmitCGO_ENABLED=0aus. Cgo zu deaktivieren erzeugt ein voll statisches Binary ohne Abhängigkeit von System-C-Libraries, und genau das lässt uns es auf einem minimalen Image laufen.
Die runtime Stage ist bewusst winzig:
- Runtime-Image:
- Startet von einem reinen
alpine:3.20. - Installiert
ca-certificates, damit deine App ausgehende HTTPS-Requests machen kann, zum Beispiel an eine Datenbank oder eine Third-Party-API. Ohne sie schlagen TLS-Calls mit Zertifikatsfehlern fehl. - Kopiert nur das kompilierte Binary aus der Build-Stage.
- Exponiert Port 8080 und führt das Binary aus.
Deployment
Du kannst diesen Docker Container bei jedem Cloud-Anbieter deployen, der Docker unterstützt. Du könntest zum Beispiel Plattformen wie Heroku, DigitalOcean oder AWS ECS nutzen. Da ich Mitgründer von Sliplane bin, zeig ich dir, wie du es dort deployst.
Nach der Anmeldung kannst du einen neuen Service erstellen, indem du dein GitHub Repository auswählst. Behalt dann einfach die Standardeinstellungen bei und klick auf Deploy.

Nach dem Deployment ist deine Go App unter einer Subdomain von sliplane.app verfügbar, normalerweise ist das einfach dein Service-Name.
Du kannst auch die Logs deiner App sehen, Metriken wie CPU- und Speichernutzung einsehen, persistenten Speicher hinzufügen und vieles mehr. Wann immer du in dein Repository pushst, deployed Sliplane deine App automatisch.
Wenn du Sliplane ausprobieren möchtest, sind die ersten 2 Tage kostenlos! Probier es aus und lass mich wissen, was du davon hältst :)
Nächste Schritte
Wenn du das kleinstmögliche Image willst, kannst du die Alpine-Runtime durch scratch ersetzen und die CA-Zertifikate manuell reinkopieren. Brauchst du dabei Hilfe oder beim Hinzufügen eines Health-Check-Endpoints? Melde dich gerne!
Bis dann,
Lukas