Guide 1 of 12
Getting started
Bogie is a CLI, not a library. It renders a new Go service onto disk and then gets out of the way: the app it generates never imports Bogie, so deleting the tool tomorrow does not touch the app.
Install
go install github.com/bogie-go/bogie@latest
@latest is the newest tagged release, v0.2.1 at the time of writing, and bogie version prints it. Go 1.25 or newer is the one prerequisite; Postgres runs in Docker from the app's own compose file. For main as it stands, go install github.com/bogie-go/bogie@main; from a clone, go install ..
Generate a service
bogie new blog
This is rails new: it writes an API-only, Postgres-only Go service, runs go mod tidy, and makes the development credentials file. Two flags change what it writes:
--module=PATHsets the Go module path, if it should not be the app's name.--jobsadds River on the same Postgres: a worker role,app/jobs, andg job. See Background jobs.
The generated tree
Rails-shaped on purpose, so a Rails developer knows where to look:
main.go dispatches: serve | migrate | db
cli.go the migrate and db subcommands
app/
application.go wiring: migrate at boot, config, connections, controllers
controllers/
application.go root Server, one NAMED field per controller
routes.go the whole routing table
welcome.go the development page at /; gone once a route claims /
middlewares/ request id · logging · recover
services/database/ db create and drop, through the maintenance database
services/migrate/ goose over the embedded migrations and seeds
models/ sqlc output plus the store
views/ wire contracts; domain structs never double as wire structs
domain/ THE DOMAIN; imports nothing third-party
config/ credentials file + env → validated struct, no globals
deploy.yml Kamal 2, staging; deploy.production.yml overlays it
.kamal/secrets what Kamal substitutes: the master key and the registry password
Dockerfile one image, every role; keys never enter it
db/
db.go go:embed of migrate/*.sql and seeds/*.sql
migrate/ goose SQL, timestamped; g model writes the first
seeds/ goose SQL in its own version table; development data
lib/logger/
There is no table yet, as a fresh rails new has none either: Models and migrations writes the first.
Bring up the database and serve
cd blog
make up
bogie db:prepare
bogie server
make up starts Postgres under Docker Compose on port 5440 and waits until it answers. bogie db:prepare is rails db:prepare: create the database if it does not exist, migrate, seed. bogie server (or bogie s) runs the HTTP server; it migrates at boot, the way a deployed container does. In development it also runs under Air, so saving a file rebuilds and restarts it; since migrations are embedded in the binary and applied at boot, a new one is picked up on the next reload too. bogie worker reloads the same way, to its own binary, so the two run side by side in two terminals. Production runs the compiled binary, untouched; make server and make worker are the plain, one-boot equivalents.
Visit / in development for a welcome page with the environment, the listen address and the Go version, and GET /healthz for the plain text a load balancer checks. The welcome page disappears the moment any controller claims /; in every other environment / is a plain 404 until something is mounted there.
Check the app is sound
bin/ci
The whole pipeline, run on the machine you already have: it rebuilds the test database from the migrations, rolls them down and back up, checks the generated models are current, runs gofmt, vet, golangci-lint, the build, and the test suite. A green run on a clean tree signs the commit off with gh signoff, if that extension is installed.
bogie doctor is worth running any time the app feels off: it checks every marker the generators write is intact exactly once, that the pinned tools are still in go.mod, that the layout files generators depend on exist, and that every controller is both constructed and mounted. See Testing and CI for what each step of bin/ci does.