Eine Go-App bereitstellen
Um eine Go-App auf Lizard (lizard.build) bereitzustellen, lade ein Modul mit einer go.mod-Datei hoch oder pushe es. lizardpack baut es mit der Go-Version aus der go-Zeile, kompiliert ein statisches Binary (CGO_ENABLED=0) und führt es unter Alpine Linux aus. Der Service-Port ist 8080, und Lizard übergibt ihn deinem Prozess in PORT. Lies also PORT aus und lausche auf allen Interfaces.
Teststatus: Die Beispiel-App unten wird lokal mit Go 1.24 gebaut und läuft, und ihren Build-Plan haben wir mit lizardpack geprüft, dem Build-Planer, den Lizard ausführt. Mit dieser Anleitung haben wir sie noch nicht vollständig bereitgestellt.
Bevor du beginnst
- Ein Go-Modul mit
go.modim Verzeichnis, das du bereitstellst, undgo.sum, falls es Abhängigkeiten hat. - Lizard CLI, angemeldet mit
lizard login, auf Pro oder in der 7-tägigen Pro-Testphase (Karte erforderlich). Siehe Preise.
Eine minimale App
go.mod:
module example.com/hello
go 1.24main.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.Fprintln(w, "Hello from Go on Lizard")
})
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "ok")
})
log.Printf("listening on :%s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}":"+port lauscht auf allen Interfaces. Eine Adresse wie 127.0.0.1:8080 nimmt nur Verbindungen aus dem Container selbst an, und das Deployment wird nie healthy.
Lokal prüfen:
go run .
curl http://localhost:8080/healthzWas lizardpack baut
| Schritt | Was passiert |
|---|---|
| Erkennung | go.mod, go.work oder eine beliebige .go-Datei. lizardpack prüft Go vor Node.js und Python. |
| Go-Version | Die go-Zeile in go.mod, nur Haupt- und Nebenversion: go 1.24.3 baut auf golang:1.24-alpine. Ohne go.mod Go 1.24. |
| Build | go mod download, danach CGO_ENABLED=0 GOOS=linux go build -ldflags='-s -w' -o /app/server <package> |
| Main-Paket | Das Stammverzeichnis; ./cmd, wenn cmd/main.go existiert; sonst das alphabetisch erste cmd/<name>/main.go |
| Laufzeit | alpine:3.19 mit ca-certificates und tzdata. lizardpack kopiert das ganze Quellverzeichnis neben das Binary nach /app, damit relative Pfade wie templates/ und static/ weiter funktionieren. |
| Start und Port | /app/server auf Port 8080 |
Das generierte Dockerfile:
FROM golang:1.24-alpine AS build
WORKDIR /app
COPY go.mod go.sum* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags='-s -w' -o /app/server .
FROM alpine:3.19
RUN apk add --no-cache ca-certificates tzdata
WORKDIR /app
COPY --from=build /app /app
EXPOSE 8080
CMD ["/app/server"]Lass Build- und Startbefehl des Service leer, um dieses Image zu bekommen. Ist einer davon gesetzt, schreibt Lizard aus diesen Befehlen ein anderes Dockerfile und ignoriert die go-Zeile: Ein Befehl go build … baut dann auf Go 1.24. Wenn du jeden Schritt selbst steuern willst, committe ein eigenes Dockerfile; siehe Einen Docker-Container aus einem Dockerfile deployen.
Bereitstellen
Im Stammverzeichnis des Moduls:
lizard init --name go-app
lizard add --service api
lizard up --service api --port 8080lizard up lädt das Verzeichnis hoch, baut es auf den Build-Maschinen von Lizard und gibt die URL aus. Auf dem Rechner, auf dem du den Befehl ausführst, brauchst du weder Docker noch Go. Für git push to deploy verbinde ein GitHub-Repository mit lizard add -r your-org/your-app -n api und prüfe dann, ob lizard port --service api den Wert 8080 ausgibt.
Frameworks
- net/http, chi, gorilla/mux: Übergib
":" + os.Getenv("PORT")anhttp.ListenAndServe, wie oben. - Gin:
r.Run()ohne Adresse liestPORTund fällt auf:8080zurück. SetzeGIN_MODE=releaseauf dem Service. - Echo, Fiber: Übergib die Adresse selbst:
e.Start(":" + os.Getenv("PORT"))oderapp.Listen(":" + os.Getenv("PORT")).
Variablen und Datenbanken
Setze die Konfiguration auf dem Service und lies sie mit os.Getenv:
lizard secrets set GIN_MODE=release API_KEY=change-me --service apiFür eine Datenbank füge Managed Postgres hinzu und übergib seine private URL mit einer Referenz:
lizard add postgres
lizard secrets set DATABASE_URL='${{postgres.DATABASE_PRIVATE_URL}}' --service apiÖffne die Verbindung dann mit deinem Treiber, zum Beispiel pgxpool.New(ctx, os.Getenv("DATABASE_URL")). Eine Änderung an einer Variable startet den Service ohne neuen Build neu.
Prüfen, ob es funktioniert
lizard logs --build --service api
lizard logs --service api --tail 100
lizard psRufe /healthz unter der URL auf, die lizard up ausgegeben hat, und danach eine Route, die echte Arbeit erledigt. Das Build-Log zeigt das golang:-Image, das der Build verwendet hat.
Häufige Probleme
| Symptom | Lösung |
|---|---|
no Go files in /app | Das Paket main liegt weder im Stammverzeichnis noch unter cmd/. Verschiebe es oder füge ein Dockerfile hinzu. |
| Das falsche Binary startet | Bei mehreren cmd/<name>/main.go baut lizardpack den alphabetisch ersten Namen. Füge ein Dockerfile hinzu, das das gewünschte Binary baut. |
SQLite schlägt mit CGO_ENABLED=0 fehl | Der Build schaltet cgo ab, daher kann mattn/go-sqlite3 nicht funktionieren. Nutze einen reinen Go-Treiber oder besser Managed Postgres: Dateien im Container gehen bei jedem Deployment verloren. |
| Das Deployment wird nie healthy | Der Prozess muss auf allen Interfaces auf PORT (oder 8080) lauschen. Siehe Service wird nie healthy. |
| Du brauchst eine neuere Go-Version | Ändere die go-Zeile, zum Beispiel mit go mod edit -go=1.25, und stelle erneut bereit. Siehe Laufzeitversionen. |
Ein Go-Prozess, der kein HTTP ausliefert, etwa ein Queue-Consumer, läuft als Hintergrund-Worker mit --port 0.
Siehe auch
Aktualisiert