Skip to main content
Every Copper binary starts the same way: you create the app, then hand it something to run. Let’s look at the main.go from a generated project:
cmd/app/main.go
copper.New() builds the app container, which parses command-line flags, loads config, and sets up the logger and lifecycle:

Runners

Anything with a Run() error method can be run by the app:
chttp.Server and csql.Migrator both implement it, and you are free to implement it with your own types, such as a job worker, a queue consumer, or a one-off script.

Run vs. Start

  • app.Run(runners...) is for short-lived work. It runs each runner in order, then shuts down. This is how the migrate binary works: app.Run(migrator).
  • app.Start(runners...) is for long-lived work. It runs each runner, then blocks until the process receives SIGINT or SIGTERM, and shuts down gracefully. This is how the HTTP server runs.
If any runner returns an error, the app logs it and exits with code 1.

Registering Cleanup with OnStop

You may register cleanup work, such as closing a database connection or flushing a client, using OnStop. Copper will run these functions during shutdown, each with a deadline context:

Running Background Goroutines

You should not use a bare go statement for long-running work, since the app has no way to wait for it during shutdown. Instead, use Lifecycle.Go. Goroutines started this way are tracked, awaited on shutdown, and recovered from panics, so a panic is logged with its stack trace instead of crashing the app:

Graceful Shutdown

Shutdown happens in two phases, which is what makes it graceful:
  1. Lifecycle.Shutdown() is a channel that closes when shutdown begins. Loops should select on it to exit.
  2. Lifecycle.Context() is a context that stays valid during shutdown so that in-flight work can finish. It is only canceled at the very end.
A long-running worker uses both:
Shutdown waits up to 30 seconds for Go goroutines to finish before running OnStop funcs and exiting. Work that can’t finish in time is abandoned, so keep background tasks incremental.