Stormkit can run long-running server processes (for example Go HTTP servers) by using the Start command setting. This option is available only on self-hosted Stormkit instances.
On a self-hosted instance, the Application Runtime is the recommended way to run
backend code. Serverless functions are a Stormkit Cloud
feature; self-hosted instances execute them by forking a short-lived node process per
request, which is fine for parity and local development but not for production traffic.
Reach for a Start command whenever your backend:
The process is reaped after 10 minutes without a request. Published environments are kept
warm by the domain ping, so this is invisible in practice; preview deployments, which are
not pinged, pay a cold start after an idle spell. Set STORMKIT_MAX_IDLE (in minutes) as
an environment variable to widen the window.
Requests reach your server through Stormkit's proxy, which applies
STORMKIT_HTTP_PROXY_TIMEOUT
(default 30 seconds) to the time your server
may take to start sending response headers. This is the only request deadline on a
self-hosted instance — the 15 second function timeout is a Stormkit Cloud limit and does
not apply here. Raise it, or set it to 0, if a request legitimately needs longer.
The runtime is not Go-specific — any process that listens on PORT works, including a
Node/Express or Fastify server. Go is used in the examples below because compiling a
binary is the most common case.
To run a Go program, you typically compile a binary during the build step and start it with the Start command.
go.mod file in your build root..go-version or mise.toml.PORT environment variable.Example .go-version:
1.22.5
Example mise.toml:
[tools]
go = "1.22.5"
In Your App > Environments > Config:
go build -o dist/app ./cmd/serverdist./dist/appThis configuration will:
dist.The start command runs from the root of the uploaded artifact, so it has to
include the server folder in the path (./dist/app, not ./app).
package main
import (
"log"
"net/http"
"os"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "3000"
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello from Go"))
})
log.Fatal(http.ListenAndServe(":"+port, nil))
}
go run ./cmd/server as the Start command, but compiling a binary is faster and more reliable.