The signal pattern can be used to ensure your long-lived processes (ie. servers) are able to handle signals being sent to the process.
import ...
type Handler struct {
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte(`{}`))
}
func main() {
  h := &Handler{}
  sigCh := make(chan os.Signal, 1)
  errCh := make(chan error, 1)
  signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
  go func() {
    err := http.ListenAndServe(":3000", h)
    errCh <- err
  }()
  for {
    select {
    case sig := <-sigCh:
      switch sig {
      case syscall.SIGHUP:
        log.Println("woot woot sighup ", sig)
        os.Exit(0)
      case syscall.SIGTERM:
        log.Println("sigterm ", sig)
        os.Exit(0)
      case syscall.SIGINT:
        log.Println("sig interrupt ", sig)
      }
    case err := <-errCh:
      log.Println(err)
      os.Exit(1)
    }
  }
}
Many thanks to @chuyeow for introducing this pattern to me.