func fileServer(r chi.Router, path string) {
	if strings.ContainsAny(path, "{}*") {
		panic("FileServer does not permit URL parameters.")
	}
	fs := http.StripPrefix(path, http.FileServer(rice.MustFindBox("build").HTTPBox()))
	path += "*"
	r.Get(path, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fs.ServeHTTP(w, r)
	}))
}
fileServer starts the file server and return the file
package service
import (
	"context"
	"log"
	"net"
	"net/http"
	"time"
	"github.com/go-chi/chi"
	"github.com/go-chi/chi/middleware"
	"github.com/golang/glog"
	"strings"
	"github.com/GeertJohan/go.rice"
	"github.com/myntra/cortex/pkg/config"
	"github.com/myntra/cortex/pkg/store"
)
type Service struct {
	srv              *http.Server
	node             *store.Node
	listener         net.Listener
	snapshotInterval int
	httpAddr         string
}
func (s *Service) Shutdown(ctx context.Context) error {
	s.srv.Shutdown(ctx)
	if err := s.node.Shutdown(); err != nil {
		return err
	}
	return nil
}
func (s *Service) Start() error {
	if err := s.node.Start(); err != nil {
		return err
	}
	go func() {
		if err := s.srv.Serve(s.listener); err != nil {
			glog.Infof("server closed %v", err)
		}
	}()
	go func() {
		ticker := time.NewTicker(time.Minute * time.Duration(s.snapshotInterval))
		for {
			select {
			case <-ticker.C:
				glog.Infof("take snapshot => %v", s.node.Snapshot())
			}
		}
	}()
	glog.Infof("======> join addr %v%v\n", getOutboundIP(), s.httpAddr)
	glog.Infof("======> open ui http://%v%v/ui or http://localhost%v/ui\n", getOutboundIP(), s.httpAddr, s.httpAddr)
	return nil
}
func getOutboundIP() net.IP {
	conn, err := net.Dial("udp", "8.8.8.8:80")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	localAddr := conn.LocalAddr().(*net.UDPAddr)
	return localAddr.IP
}