Template repository URL: http://scm.dev.dsherwin.net/dsherwin/go_service_template
This repository is a reusable template for building small Go daemons/CLIs. It provides:
- CLI commands via Kong
- A Unix RPC server (net/rpc over a Unix domain socket)
- An HTTP server (via rest_api_server) you can extend with endpoints
- Application logging through github.com/dan-sherwin/go-applog
- Runtime logging/settings/DevLogBus integration through github.com/dan-sherwin/go-app-runtime
- System data sampling (goroutine count, memory, CPU%)
- Systemd integration using takama/daemon
- Settings persistence via app_settings
- TeamCity CI setup, including an optional Deploy configuration via rsync/SSH
- A bootstrap tool to safely rename the module and app for a new project
On macOS, this template is intended for development; production artifacts target Linux.
Run the bootstrap helper to safely rename the module and runtime app name.
Examples:
- Create a new app named your_app (sets both module path and APPNAME to your_app): go run ./dev/bootstrap your_app
- Preview planned changes without modifying files: go run ./dev/bootstrap -dry-run your_app
What the bootstrap tool does:
- Updates go.mod module path and rewrites Go imports that reference the old module path (AST-safe).
- Sets const APPNAME in cmd/app/consts/consts.go.
- Rewrites README.md with app-specific starter content.
- Updates GoLand run configurations under
dev/runConfigurations. - Updates
dev/build-dev.shwith the new application binary and settings name. - Updates .teamcity/settings.kts:
- param("app.name", "...")
- the project description ("CI for ...")
- ldflags import paths to match the new module
- Runs go mod tidy.
- Updates
.gormdb2struct.toml,.golangci.yml, anddev/ci-local.shwhere the old module path appears.
After bootstrapping:
- Open the project in GoLand; it will re-index automatically.
- Build and test: go build ./... go test -race ./... ./dev/ci-local.sh
- Update any deployment-specific settings (e.g., Deploy target in .teamcity/settings.kts) as needed.
-
macOS/Linux (dev): ./dev/build-dev.sh ./build/dev/service_template run
The first development build copies an existing
build/service_template.dbtobuild/dev/service_template.dbwhen the new settings database does not exist. Native development binaries remain separate from production output, and the script targets the current Go host regardless of ambient productionGOOSorGOARCHvalues. -
Linux production build (as in TeamCity): GOOS=linux GOARCH=amd64 CGO_ENABLED=0
go build -ldflags "-X 'scm.dev.dsherwin.net/dsherwin/go_service_template/cmd/app/consts.Version=0.1.0'" -o ./dist/service_template ./cmd
The binary exposes a CLI with commands registered under cmd/app/commands. See internal/foo for examples of adding a command and a setting. To add a command, include the CommandDef inside app.commands.Commands and set defaults in app.Setup(), for example:
utilities.MergeInto(vars, foo.CommandVars())
- Use
applog.Info,applog.Warn,applog.Error,applog.Debug, andapplog.Debug2throughapplog.Debug5in service code. go-applogowns platform logging setup;go-app-runtimeowns settings, RPC commands, and DevLogBus publishing.- Runtime settings:
log_level,devlogbus_enabled, anddevlogbus_endpoint. - Operator commands:
logging status,logging level, and thedevlogbuscommands in the logging command group. - Standard log keys include app, version, commit, buildDate, pid, user, and error.
- Unix domain socket:
/tmp/<APPNAME>-rpc.sock(0660 perms) - Start server as part of daemon run path; client helpers dial per call and close
- rest_api_server started after daemon setup; add your own endpoints as needed
- Consider adding /healthz and /ready if useful
- Install/remove/start/stop/status via CLI under the Systemd command group
- Uses takama/daemon to register the service
- Build info is injected via -ldflags into cmd/app/consts (Version, Commit, BuildDate) and shown by the hidden buildinfo command
dev/ci-local.shruns the local validation pass:go mod tidy,go build,go vet,go test -race,golangci-lint,govulncheck, andgofmt -s.- The script pins the local Go toolchain default to
go1.26.5, matching the minimum patched Go release required by the vulnerability gate.
- .teamcity/settings.kts contains a Build configuration:
- go mod tidy, go vet, go test -race, and a Linux/amd64 build with ldflags
- It also contains an optional Deploy configuration using rsync/SSH to a target host and a systemctl restart. Parameters to set per environment:
- deploy.dest_user (default dsherwin)
- deploy.dest_host (e.g., service-host.example.internal)
- deploy.dest_path (default /usr/local/%app.name%/%app.name%)
- service.name (defaults to %app.name%)
- Keep runtime app name centralized in cmd/app/consts/consts.go (APPNAME), default is "service_template".
- An example package exists at internal/foo to demonstrate settings and commands integration. To remove it, delete the internal/foo directory and remove any references to it:
- app.Setup(): remove utilities.MergeInto(vars, foo.CommandVars())
- cmd/app/commands/commands.go: remove foo.FooCommandDef from the Commands struct
- Any imports referencing internal/foo
- Prefer the bootstrap tool to rename this template rather than search/replace.
- See .junie/guidelines.md for project conventions.