Deploy Go on Temps
Temps detects a Go app from go.mod, compiles a static binary with CGO_ENABLED=0 and runs it on a Debian slim image behind automatic HTTPS. Your server only has to listen on the PORT Temps sets; Gin, Echo, Chi, Fiber and net/http all work.
This guide describes how the nightly release channel builds your app, using the Autopack builder. Beta (v0.1.0-beta.56) also builds with Autopack, but some details below may differ. Earlier releases and the stable channel build with Nixpacks and behave differently. To run nightly, see Release channels.
For an overview of self-hosting Go, including costs, see Deploy Go to your own server. Every framework and the preset it needs is listed under Supported platforms; the Rust guide follows the same pattern.
Quickstart
From your project root, deploy with your preferred package manager:
npx @temps-sdk/cli up
Temps detects your go.mod, compiles a static binary with go build, and runs it on a Debian slim image. The Go version comes from the go line in go.mod, and defaults to 1.23, which no longer gets security fixes, so keep the go line in go.mod current (Go 1.27 and 1.26 are the supported releases as of October 2026).
Temps builds the main package in the repository root, or the single cmd/<name>/main.go if there is no root main.go. If your repository has several commands under cmd/, pick one in a .temps.yaml file:
build:
build_command: go build -o /app/bin/app ./cmd/api
What Temps handles automatically
| Feature | How Temps handles it |
|---|---|
| Build | go build -ldflags='-s -w' with CGO_ENABLED=0 (a static binary) |
| Image | Multi-stage build: the binary is copied into a Debian slim runtime image |
| HTTPS | Let's Encrypt, auto-renewed |
| Port | PORT env var injected, defaults to 8080 |
| Health checks | HTTP check on / at deploy time, or the path set in .temps.yaml |
| Startup | Near-instant — static binary, no runtime |
Dockerfile (optional)
Temps auto-generates a Dockerfile for Go projects. If you want full control, add your own:
# Build stage
# Match the go line in go.mod
FROM golang:1.27-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o app .
# Run stage
FROM alpine:latest
RUN apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=builder /app/app .
EXPOSE 8080
CMD ["./app"]
Reading PORT from environment
Make sure your server reads the PORT environment variable:
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(":"+port, nil))
With Gin, pass the same address to Run:
r := gin.Default()
r.GET("/", func(c *gin.Context) { c.JSON(200, gin.H{"status": "ok"}) })
r.Run(":" + os.Getenv("PORT"))
Echo (e.Start(":" + port)), Chi (http.ListenAndServe(":"+port, r)) and Fiber (app.Listen(":" + port)) work the same way. An address that starts with : listens on all interfaces, which is what Temps needs.
Managed PostgreSQL
Create a PostgreSQL database under Databases → Create database, then link it from your project's Databases page. Temps injects the connection string as POSTGRES_URL:
db, err := sql.Open("pgx", os.Getenv("POSTGRES_URL"))
See Deploy with a Database for all the injected variables.
Platform behavior
These rules apply to every app deployed on Temps, regardless of framework.
The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.
Health checks
After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.
- Path:
/(the root of your application) by default - Success: 2 consecutive responses with a 2xx, 3xx, 404 or 405 status code
- Timeout: 300 seconds (5 minutes) for the app to become healthy, fixed in v0.1.0-beta.56. If the app answers with error responses (other 4xx, or 5xx) for 60 seconds in a row, the deployment fails sooner. From the next release the timeout is configurable from 30 to 3600 seconds under Project → Settings → Build & deploy
- Retry interval: 2 seconds between successful checks, 5 seconds after an error response or a failed connection
Connection errors and other 4xx or 5xx responses are retried until the timeout; if the app hasn't passed by then, the deployment fails. The check runs once, at deploy time. To check a different path, add a .temps.yaml to your repository root:
health:
path: /healthOnly path is used. Other health fields (status, interval, timeout, retries) are accepted but currently have no effect.
/health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.Auto-injected environment variables
Temps injects these variables into every deployment automatically:
| Variable | Value | Description |
|---|---|---|
PORT | Resolved port | The port your app must listen on |
HOST | 0.0.0.0 | Bind address |
SENTRY_DSN | Auto-generated | Error tracking endpoint |
TEMPS_API_URL | Your Temps URL | Platform API endpoint |
TEMPS_API_TOKEN | Deployment token | Authentication for Temps SDKs |
OTEL_EXPORTER_OTLP_ENDPOINT | Your Temps OTLP URL | OpenTelemetry trace collection |
OTEL_SERVICE_NAME | Project name | Service identifier for traces |
You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.