HTTP service template for Go: Gin, configuration via environment variables, OpenTelemetry hooks, and a small web UI shell.
NOTE: This template and the instantiate tool are designed with defaults that assume you'll use certain services, like GitHub. If you intend to use alternative infrastructure or services, you may need to manually update portions of the generated project to fit your requirements.
Pick one path:
gonew copies this module into a new directory and sets module in go.mod to your path. After that, instantiate reads that module path from go.mod and rewrites the rest of the tree (CI, Docker, HTML, command folder name, etc.). You do not pass -module unless you want to override go.mod.
- Install Go 1.26+.
- Run
gonewwith this template’s module path and your target module path (replaceYOUR_ORGandYOUR_REPO):
gonew go.rtnl.ai/go-service-template github.com/YOUR_ORG/YOUR_REPOcdinto the directorygonewcreated (by default it matches your repo name).- Run
instantiatefrom that directory:
go run ./tools/instantiate \
-github-owner=YOUR_ORG \
-github-repo=YOUR_REPOIf your module path is already under github.com/YOUR_ORG/YOUR_REPO, you can omit -github-owner and -github-repo when they match the path.
Use this when you created the repo from the template on GitHub (or cloned this repo and pointed origin at your remote) without running gonew. Then go.mod still names this template’s module until instantiate runs, so you must pass -module ( instantiate will refuse to guess when go.mod still contains go.rtnl.ai/go-service-template).
- On GitHub, use Use this template to create a new repository (or clone this repo and point
originat your new remote). - Clone your new repository and
cdto its root. - Install Go 1.26+ and run:
go run ./tools/instantiate \
-module=github.com/YOUR_ORG/YOUR_REPO \
-github-owner=YOUR_ORG \
-github-repo=YOUR_REPOIf -module is already under github.com/..., you can omit -github-owner and -github-repo when they match the path (the tool will parse them). For non-GitHub module paths, set owner and repo explicitly so README badges and container image lines update correctly.
This repo ships README.md.template, a short stub README for projects generated from the template (badges, local development, license placeholder). instantiate applies the same string substitutions there as everywhere else.
-
With
-delete-self: After substitutions,instantiatereplacesREADME.mdwith the contents ofREADME.md.template, deletesREADME.md.template, then removestools/instantiate. Your repo ends up with one README aimed at users of your service, not this template’s setup instructions. -
Without
-delete-self:README.mdstays as this long template HOWTO until you change it yourself.README.md.templateis updated in place with your module name and paths—when you are ready, replaceREADME.mdwith that file (or merge what you need), deleteREADME.md.template, and removetools/instantiatemanually.
| Flag | Meaning |
|---|---|
-module |
Go module path (omit after gonew when go.mod already names your module; required for the GitHub-template path above) |
-service |
Command and service name (default: last segment of the module path) |
-prefix |
Lowercase confire prefix for env vars (default: letters and digits from -service) |
-container-repository |
Full container image repository, registry + path without a tag (default: gcr.io/<github-owner>-habanero/<github-repo>) |
-version |
Set pkg/version.go to a semver, e.g. 0.1.0 or 2.0.0-beta.1. Omit when upgrading and you want to keep existing version constants. |
-prerelease / -prerelease-number |
Used with -version when the version string has no prerelease segment |
-no-golang-tools |
Skip post-edit checks (by default the tool runs go mod tidy, go fix three times, go vet ./..., and go test ./...; failures print warnings and do not abort the run) |
-dry-run |
Print planned edits only; no writes and no post-edit Go toolchain |
-skip-verify |
Skip the scan for leftover template text |
-delete-self |
Replace README.md from README.md.template, then remove tools/instantiate (cannot be used with -dry-run) |
Commit the result and open a PR as usual.
On a real run, instantiate runs a post-edit pass unless you pass -dry-run or -no-golang-tools. That pass is, in order: go mod tidy, go fix ./... run three times, go vet ./..., and go test ./.... A failed step does not stop the rest: the run still finishes, and you will see a line on stderr starting with instantiate: warning:. Use -no-golang-tools when you only want literal substitutions and the cmd/ folder rename, without invoking other go subprocesses afterward.
In the same run, unless you pass -skip-verify, the tool also fails the process if any old template text is still present in the tree (the tools/instantiate tree is not checked, because that code is not rewritten). For a self-check of the instantiate program, from a temp copy of the template you can run go test ./tools/instantiate.
GitHub: In the template repository settings, enable Template repository so others can use Use this template.
This project is licensed under the BSD 3-Clause License. See LICENSE for details.