Skip to content

Go ​

A minimal app ​

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")
	})
	log.Printf("listening on %s", port)
	log.Fatal(http.ListenAndServe(":"+port, nil))
}

":"+port listens on every interface. Gin's r.Run(), Echo's e.Start(":"+port) and Fiber's app.Listen(":"+port) work the same way.

What Zenavo detects ​

A repository with go.mod builds with zbpack as Go. The Go version comes from the go line in go.mod. The build runs go mod download and go build with CGO_ENABLED=0, and the binary runs on a small Alpine image.

zbpack builds the package in the root directory. When main lives elsewhere, such as cmd/server, set the entry under Settings → Build → zbpack options:

sh
ZBPACK_GO_ENTRY=./cmd/server

For a monorepo, set the service's Root Directory to the folder with go.mod instead.

Deploy ​

  1. Add Service → GitHub, pick the repository and branch.
  2. Click Next, check the preview shows go with your Go version, and click Deploy.
  3. Generate a domain on the Networking tab.

Connect a database ​

Add PostgreSQL to the project and set on the Go service:

sh
DATABASE_URL=${POSTGRESQL_CONNECTION_STRING}

pgx, database/sql with lib/pq, GORM and sqlc all accept this URL.

Your own Dockerfile ​

A Dockerfile in the root directory is used instead of zbpack, for example to include files next to the binary or to build with cgo:

dockerfile
FROM golang:1.26-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /server ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

The service's port comes from EXPOSE.

Common problems ​

SymptomCause
Deploy never becomes healthyThe server listens on localhost:8080 or ignores PORT. Listen on ":"+os.Getenv("PORT").
no Go files in /srcmain is not in the root directory. Set ZBPACK_GO_ENTRY or the root directory.
The binary cannot find templates or static fileszbpack copies only the binary into the image. Embed them with //go:embed, or use a Dockerfile.
x509: certificate signed by unknown authority from distroless or scratch imagesThe image has no CA certificates. Use distroless/static, which has them, or copy /etc/ssl/certs.

Not affiliated with Zeabur.