From 60dada86a644d650470ffea3966d6e8e521745e2 Mon Sep 17 00:00:00 2001 From: Stavros Date: Tue, 4 Nov 2025 18:42:04 +0200 Subject: [PATCH] feat: add support for listening on unix sockets --- cmd/root.go | 1 + internal/bootstrap/app_bootstrap.go | 20 ++++++++++++++++++++ internal/config/config.go | 1 + internal/controller/context_controller.go | 10 +++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index ed16add..aa1ce50 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -70,6 +70,7 @@ func (c *rootCmd) Register() { {"trusted-proxies", "", "Comma separated list of trusted proxies (IP addresses or CIDRs) for correct client IP detection."}, {"disable-analytics", false, "Disable anonymous version collection."}, {"disable-resources", false, "Disable the resources server."}, + {"socket-path", "", "Path to the Unix socket to bind the server to."}, } for _, opt := range configOptions { diff --git a/internal/bootstrap/app_bootstrap.go b/internal/bootstrap/app_bootstrap.go index fdbd382..7c5ae8c 100644 --- a/internal/bootstrap/app_bootstrap.go +++ b/internal/bootstrap/app_bootstrap.go @@ -286,6 +286,26 @@ func (app *BootstrapApp) Setup() error { log.Debug().Msg("Starting database cleanup routine") go app.dbCleanup(database) + // If we have an socket path, bind to it + if app.config.SocketPath != "" { + // Remove existing socket file + if _, err := os.Stat(app.config.SocketPath); err == nil { + log.Info().Msgf("Removing existing socket file %s", app.config.SocketPath) + err := os.Remove(app.config.SocketPath) + if err != nil { + return fmt.Errorf("failed to remove existing socket file: %w", err) + } + } + + // Start server with unix socket + log.Info().Msgf("Starting server on unix socket %s", app.config.SocketPath) + if err := engine.RunUnix(app.config.SocketPath); err != nil { + log.Fatal().Err(err).Msg("Failed to start server") + } + + return nil + } + // Start server address := fmt.Sprintf("%s:%d", app.config.Address, app.config.Port) log.Info().Msgf("Starting server on %s", address) diff --git a/internal/config/config.go b/internal/config/config.go index 40c9751..753f971 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -41,6 +41,7 @@ type Config struct { TrustedProxies string `mapstructure:"trusted-proxies"` DisableAnalytics bool `mapstructure:"disable-analytics"` DisableResources bool `mapstructure:"disable-resources"` + SocketPath string `mapstructure:"socket-path"` } // OAuth/OIDC config diff --git a/internal/controller/context_controller.go b/internal/controller/context_controller.go index 80ec61a..592aa3a 100644 --- a/internal/controller/context_controller.go +++ b/internal/controller/context_controller.go @@ -97,7 +97,15 @@ func (controller *ContextController) userContextHandler(c *gin.Context) { } func (controller *ContextController) appContextHandler(c *gin.Context) { - appUrl, _ := url.Parse(controller.config.AppURL) // no need to check error, validated on startup + appUrl, err := url.Parse(controller.config.AppURL) + if err != nil { + log.Error().Err(err).Msg("Failed to parse app URL") + c.JSON(500, gin.H{ + "status": 500, + "message": "Internal Server Error", + }) + return + } c.JSON(200, AppContextResponse{ Status: 200,