We're using multi-stage-builds here to trim the crap out of the final artifact.
- dev - this stage is used for local development.
docker build --target dev --tag goat:dev && docker run --env PORT=9000 goat:dev
docker-compose run goat
docker-compose up
make up
All do (appx) the same thing:
- create a dev image with a code mounted volume
- runs container with cmd
air
.
- prod - this stage is used for deployment.
It takes the built binary from dev
and puts it in a minimal alpine
image.
That's it.
https://github.com/cosmtrek/air
Live reloading configuration for Go apps.
Master linter for Golang. Runs a lot of checks right now which I thought might be helpful. If it becomes to opinionated we can tone down the settings in this file.
up
shell
main.go
is always the main entrypoint in Go, it exists by
itself, has the line package main
in it, and has a single func main()
defined.
This service uses FX as the dependency
injection framework. Convention is packages that are wrapped in FX-compatible
packages are suffixed with fx
. For example, I wrapped the zap
package in
an FX compatible package and called it zapfx
(same with envfx
).
FX compatible packages have a single file called module.go
, in which, a
single exported variable called Module
is defined. This allows very clean
dependency management in main.go
:
app := fx.New(
zapfx.Module,
envfx.Module,
...
)
Dependencies added to the app lifecycle are long-lived, which means they are shared by all requests concurrently. This is very good use of resources, but means you should be careful about dependency-owned variables, and keep anything dangerous allocated in thread scope (just make new stuff in the function call and everything will be ok).
The logging framework we use here is zap. It is purpose built for structured backend logging which allows it to be not magical, thus fast.
golangci-lint
is an awesome meta linter, if a lint rule is obnoxious, you can
find examples of how to ignore it in [./.golangci.yml].
Use goimports -local github.com/banditml ./...
to format the source code.
I really like pretty formatting, if you do too:
brew tap kyoh86/tap
brew install richgo
then replace every go
command with richgo
, like:
richgo test ./...