Go app hosting with real binaries, systemd and graceful restarts
Go compiles to a single binary, which makes hosting it simple until you need to ship a new version without dropping connections, keep the old binary for rollback, and run background workers next to the API. Deployment builds your Go service on your own server (or takes the binary from your CI), runs it under systemd, and switches releases only after the new process passes its health check.
What Deployment detects in a Go module
go.mod marks a Go project and its go directive picks the toolchain version. Deployment looks for main packages: a single main.go at the root, or several commands under cmd/ (for example cmd/api and cmd/worker), and offers one process per command. A Makefile with a build target or a .goreleaser.yaml is used as the build step when present. Embedded assets through embed need nothing extra; a web/ or frontend/ folder with a package.json adds a Node build before compilation.
- Go toolchain version from go.mod, installed per site
- One managed process per command under cmd/
- CGO disabled by default for static binaries, enabled when your module needs it
- Optional Node build for embedded frontends
What Deployment installs for Go app hosting
Go services need very little on the server, and Deployment keeps it that way. Provisioning hardens the host (firewall, key-only SSH, unattended security updates, swap), installs the Go toolchain only if you build on the server, and sets up nginx or Caddy as the TLS-terminating reverse proxy with HTTP/2 and gzip. If you prefer, Caddy can sit in front with automatic certificates, or your binary can listen on a private port while the proxy handles domains, aliases, redirects and Let's Encrypt.
A Go build and deploy script
The module and build caches live in a shared folder, so incremental builds are quick. If your CI already produces binaries, replace the build lines with a download of the release artifact; Deployment does not care where the binary comes from, only that it starts and passes the health check.
cd "$RELEASE_PATH" export CGO_ENABLED=0 GOFLAGS=-trimpath go mod download go build -ldflags="-s -w -X main.version=$COMMIT_SHA" -o bin/api ./cmd/api go build -ldflags="-s -w" -o bin/worker ./cmd/worker ./bin/api migrate
systemd units, workers and cron for Go services
Each command runs as its own systemd unit with Restart=on-failure, a memory limit, an environment file with your encrypted variables, and journald logs streamed to the panel. Workers that consume a queue (Redis streams, NATS, RabbitMQ or a database table) run as separate units and receive SIGTERM on deploy, so a well-behaved worker finishes its current task and exits. Periodic tasks run as cron jobs (./bin/api cleanup --older-than=30d) with every run's output stored in the cron log.
Graceful restart and zero downtime for Go
Deployment starts the new binary on a fresh port next to the old one, calls the health endpoint (for example /healthz), then points the proxy at the new process. The old process receives SIGTERM and should call http.Server.Shutdown with a timeout, which stops accepting new connections and lets in-flight requests finish. Go makes this a few lines of code, and Deployment waits for the process to exit before cleaning up. Every release keeps its binaries, so rollback means starting the previous binary and switching the proxy back, in seconds and without a rebuild. See zero downtime deployment for the full sequence and deploy from git for branches and webhooks.
srv := &http.Server{Addr: ":" + os.Getenv("PORT"), Handler: mux}
go srv.ListenAndServe()
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGTERM)
<-stop
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Second)
defer cancel()
srv.Shutdown(ctx)PostgreSQL, MySQL and Redis for Go services
Create PostgreSQL, MySQL or MariaDB databases with their own users and grants, and Redis for caching, rate limits and queues. Connection strings live in encrypted environment variables per environment. Migrations run from your binary, from golang-migrate, goose or Atlas, as a line in the deploy script, before the release switch. Backups go to your own S3-compatible bucket on the schedule your plan allows.
Which plan fits your Go app hosting
| Plan | Monthly | Yearly, per month | Servers | Sites |
|---|---|---|---|---|
| Starter | 49 USD | 24 USD | 3 | 15 |
| Team | 199 USD | 99 USD | 15 | 100 |
| Agency | 499 USD | 249 USD | 60 | unlimited within servers |
| Enterprise | 1 499 USD | 749 USD | 250 | unlimited within servers |
Go services are light, so a few microservices fit easily on Starter. Teams that run many services across regions, or need roles and the audit log, fit Team. Enterprise adds SSO (SAML) and a 99.9 percent SLA.
Go app hosting questions
Do I have to build on the server?
No. You can build on the server or download a binary your CI built. Either way the release gets a health check and a one-click rollback.
Can I run gRPC services?
Yes. The proxy can forward HTTP/2 and gRPC traffic to your service, or the service can listen directly on a port you open in the firewall.
How do I run several commands from one repository?
Each main package under cmd/ becomes its own process with its own command, logs and restart policy, all released together from one deploy.
Can I try Deployment before I pay?
Yes. The home page has a free one-time demo: paste a public repository URL and see the detected stack, the server plan and the first lines of the deploy script. Plans start at 49 USD a month, or 24 USD a month billed yearly.
Ship your Go binary with confidence
Connect a server and push. Deployment handles the switch.
$ git push origin main
✓ build release 20261019-142210
✓ health check 200
✓ switch current 0.4 s
$