package main import ( "context" "errors" "fmt" "os" "path/filepath" "github.com/ardanlabs/conf/v3" "tailscale.com/tsnet" "alin.ovh/homestead/domain/content/publisher" "alin.ovh/homestead/domain/web/server" "alin.ovh/homestead/shared/env" "alin.ovh/x/log" ) type Options struct { Development bool `conf:"flag:dev"` Publisher publisher.Options Server server.Options } func main() { options := &Options{} help, err := conf.Parse("", options) if err != nil { if errors.Is(err, conf.ErrHelpWanted) { fmt.Println(help) os.Exit(1) } panic("parsing runtime configuration: " + err.Error()) } log := log.Configure(!options.Development) if options.Development { options.Publisher.Development = true } hostname := env.GetEnvFallback("TAILSCALE_HOSTNAME", "barkeep") stateDir := env.GetEnvFallback("XDG_STATE_HOME", "~/.local/state") ts := &tsnet.Server{ Dir: filepath.Join(stateDir, "barkeep"), Hostname: hostname, Ephemeral: options.Development, } lc, err := ts.LocalClient() if err != nil { log.Fatal("error creating tailscale local client", "error", err) } options.Publisher.LocalClient = lc pub, err := publisher.New(&options.Publisher, log.Named("publisher")) if err != nil { log.Fatal("error running publisher", "error", err) } listener, err := ts.ListenTLS("tcp", ":443") if err != nil { log.Fatal("error creating tailscale listener", "error", err) } options.Server.Listener = listener srv, err := server.New(&options.Server, log.Named("server")) if err != nil { log.Fatal("error creating server", "error", err) } if err := srv.HostApp(pub.App); err != nil { log.Fatal("error hosting app", "error", err) } go func() { _, err := ts.Up(context.Background()) if err != nil { log.Error("error starting tailscale", "error", err) } log.Info("starting server", "base_url", options.Publisher.BaseURL) }() if err := srv.Start(); err != nil { log.Fatal("error starting server", "error", err) } defer ts.Close() }