diff --git a/cmd/pulse/commands_test.go b/cmd/pulse/commands_test.go index 53487ec8b..548756070 100644 --- a/cmd/pulse/commands_test.go +++ b/cmd/pulse/commands_test.go @@ -909,7 +909,7 @@ func TestRunServer_FrontendFail(t *testing.T) { // Keep l open defer l.Close() - t.Setenv("BACKEND_HOST", "127.0.0.1") + t.Setenv("BIND_ADDRESS", "127.0.0.1") // Set frontend port to busy port t.Setenv("FRONTEND_PORT", fmt.Sprintf("%d", port)) diff --git a/frontend-modern/src/types/config.ts b/frontend-modern/src/types/config.ts index 9c1dcbd54..9b4714503 100644 --- a/frontend-modern/src/types/config.ts +++ b/frontend-modern/src/types/config.ts @@ -37,7 +37,6 @@ export interface SystemConfig { temperatureMonitoringEnabled?: boolean; // Collect CPU/NVMe temperatures via SSH sshPort?: number; // SSH port for temperature monitoring (default: 22) allowedOrigins?: string; // CORS allowed origins - backendPort?: number; // Backend API port (default: 7655) frontendPort?: number; // Frontend UI port (default: 7655) theme?: string; // Theme preference: 'light' | 'dark' | undefined (system default) fullWidthMode?: boolean; // Full-width layout mode preference @@ -181,7 +180,7 @@ export const DEFAULT_CONFIG: { system: SystemConfig; } = { system: { - connectionTimeout: 10, + connectionTimeout: 60, autoUpdateEnabled: false, updateChannel: 'stable', autoUpdateCheckInterval: 24, @@ -191,7 +190,6 @@ export const DEFAULT_CONFIG: { temperatureMonitoringEnabled: true, sshPort: 22, allowedOrigins: '', - backendPort: 7655, frontendPort: 7655, }, }; diff --git a/internal/api/ai_handlers_test.go b/internal/api/ai_handlers_test.go index bdd911bde..add1dcaf9 100644 --- a/internal/api/ai_handlers_test.go +++ b/internal/api/ai_handlers_test.go @@ -934,7 +934,7 @@ func TestAISettingsHandler_SetConfig(t *testing.T) { handler.SetConfig(nil) // SetConfig with new config should update the handler's config - newCfg := &config.Config{DataPath: tmp, BackendPort: 9999} + newCfg := &config.Config{DataPath: tmp} handler.SetConfig(newCfg) // No assertion needed - just verifying it doesn't panic } diff --git a/internal/api/config_handlers.go b/internal/api/config_handlers.go index 704af2495..0241c527d 100644 --- a/internal/api/config_handlers.go +++ b/internal/api/config_handlers.go @@ -3268,7 +3268,6 @@ func (h *ConfigHandlers) HandleGetSystemSettings(w http.ResponseWriter, r *http. settings.PVEPollingInterval = int(h.getConfig(r.Context()).PVEPollingInterval.Seconds()) settings.PBSPollingInterval = int(h.getConfig(r.Context()).PBSPollingInterval.Seconds()) settings.BackupPollingInterval = int(h.getConfig(r.Context()).BackupPollingInterval.Seconds()) - settings.BackendPort = h.getConfig(r.Context()).BackendPort settings.FrontendPort = h.getConfig(r.Context()).FrontendPort settings.AllowedOrigins = h.getConfig(r.Context()).AllowedOrigins settings.ConnectionTimeout = int(h.getConfig(r.Context()).ConnectionTimeout.Seconds()) diff --git a/internal/api/config_handlers_cluster_additional_test.go b/internal/api/config_handlers_cluster_additional_test.go index 157e1a260..39b54efd2 100644 --- a/internal/api/config_handlers_cluster_additional_test.go +++ b/internal/api/config_handlers_cluster_additional_test.go @@ -334,7 +334,6 @@ func TestHandleGetSystemSettings_ConfigOverrides(t *testing.T) { PVEPollingInterval: 30 * time.Second, PBSPollingInterval: 90 * time.Second, BackupPollingInterval: 12 * time.Second, - BackendPort: 8081, FrontendPort: 3000, AllowedOrigins: "https://example.com", ConnectionTimeout: 15 * time.Second, diff --git a/internal/api/router_general_test.go b/internal/api/router_general_test.go index 9388d6a28..01d13168f 100644 --- a/internal/api/router_general_test.go +++ b/internal/api/router_general_test.go @@ -15,18 +15,16 @@ func TestRouter_ConfigUpdates(t *testing.T) { // Initialize Router with minimal dependencies tmpDir := t.TempDir() cfg := &config.Config{ - BackendPort: 8080, - DataPath: tmpDir, - ConfigPath: tmpDir, + DataPath: tmpDir, + ConfigPath: tmpDir, } router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0") // Test SetConfig newCfg := &config.Config{ - BackendPort: 9090, - DataPath: tmpDir, - ConfigPath: tmpDir, + DataPath: tmpDir, + ConfigPath: tmpDir, } router.SetConfig(newCfg) diff --git a/internal/api/router_integration_test.go b/internal/api/router_integration_test.go index ad1ed41ba..eb7d82ba5 100644 --- a/internal/api/router_integration_test.go +++ b/internal/api/router_integration_test.go @@ -44,7 +44,6 @@ func newIntegrationServerWithConfig(t *testing.T, customize func(*config.Config) tmpDir := t.TempDir() cfg := &config.Config{ - BackendPort: 7655, ConfigPath: tmpDir, DataPath: tmpDir, DemoMode: false, diff --git a/internal/config/config.go b/internal/config/config.go index 061a94f25..17411694e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -79,8 +79,7 @@ func IsPasswordHashed(password string) bool { // NOTE: The envconfig tags are legacy and not used - configuration is loaded from encrypted JSON files type Config struct { // Server settings - BackendPort int - BackendHost string + BindAddress string FrontendPort int `envconfig:"FRONTEND_PORT" default:"7655"` ConfigPath string DataPath string @@ -101,7 +100,7 @@ type Config struct { PVEPollingInterval time.Duration `envconfig:"PVE_POLLING_INTERVAL"` // PVE polling interval (10s default) PBSPollingInterval time.Duration `envconfig:"PBS_POLLING_INTERVAL"` // PBS polling interval (60s default) PMGPollingInterval time.Duration `envconfig:"PMG_POLLING_INTERVAL"` // PMG polling interval (60s default) - ConnectionTimeout time.Duration `envconfig:"CONNECTION_TIMEOUT" default:"45s"` // Increased for slow storage operations + ConnectionTimeout time.Duration `envconfig:"CONNECTION_TIMEOUT" default:"60s"` // Default 60s for slow storage operations BackupPollingCycles int `envconfig:"BACKUP_POLLING_CYCLES" default:"10"` BackupPollingInterval time.Duration `envconfig:"BACKUP_POLLING_INTERVAL"` EnableBackupPolling bool `envconfig:"ENABLE_BACKUP_POLLING" default:"true"` @@ -620,8 +619,7 @@ func Load() (*Config, error) { // Initialize config with defaults cfg := &Config{ - BackendPort: 3000, - BackendHost: "0.0.0.0", + BindAddress: "0.0.0.0", FrontendPort: 7655, ConfigPath: dataDir, DataPath: dataDir, @@ -1121,9 +1119,14 @@ func Load() (*Config, error) { cfg.EnvOverrides["ALLOWED_ORIGINS"] = true } - if backendHost := utils.GetenvTrim("BACKEND_HOST"); backendHost != "" { - cfg.BackendHost = backendHost - cfg.EnvOverrides["BACKEND_HOST"] = true + if bindAddr := utils.GetenvTrim("BIND_ADDRESS"); bindAddr != "" { + cfg.BindAddress = bindAddr + cfg.EnvOverrides["BIND_ADDRESS"] = true + } else if backendHost := utils.GetenvTrim("BACKEND_HOST"); backendHost != "" { + // Deprecated: BACKEND_HOST is the old name for BIND_ADDRESS + log.Warn().Msg("BACKEND_HOST is deprecated, use BIND_ADDRESS instead") + cfg.BindAddress = backendHost + cfg.EnvOverrides["BIND_ADDRESS"] = true } if sshPort := utils.GetenvTrim("SSH_PORT"); sshPort != "" { @@ -1628,9 +1631,6 @@ func SaveOIDCConfig(settings *OIDCConfig) error { // Validate checks if the configuration is valid func (c *Config) Validate() error { // Validate server settings - if c.BackendPort <= 0 || c.BackendPort > 65535 { - return fmt.Errorf("invalid backend port: %d", c.BackendPort) - } if c.FrontendPort <= 0 || c.FrontendPort > 65535 { return fmt.Errorf("invalid frontend port: %d", c.FrontendPort) } diff --git a/internal/config/config_validation_test.go b/internal/config/config_validation_test.go index 0eb1fdec2..2b04d2692 100644 --- a/internal/config/config_validation_test.go +++ b/internal/config/config_validation_test.go @@ -10,7 +10,6 @@ import ( func getValidConfig() *Config { return &Config{ FrontendPort: 7655, - BackendPort: 7656, PVEPollingInterval: 30 * time.Second, ConnectionTimeout: 10 * time.Second, AdaptivePollingMinInterval: 10 * time.Second, @@ -32,18 +31,6 @@ func TestConfig_Validate(t *testing.T) { mutate: func(c *Config) {}, isValid: true, }, - { - name: "Invalid Backend Port Low", - mutate: func(c *Config) { c.BackendPort = 0 }, - isValid: false, - errMsg: "invalid backend port", - }, - { - name: "Invalid Backend Port High", - mutate: func(c *Config) { c.BackendPort = 65536 }, - isValid: false, - errMsg: "invalid backend port", - }, { name: "Invalid Frontend Port Low", mutate: func(c *Config) { c.FrontendPort = 0 }, diff --git a/internal/config/persistence.go b/internal/config/persistence.go index 4f982067c..fc99b75fe 100644 --- a/internal/config/persistence.go +++ b/internal/config/persistence.go @@ -1058,7 +1058,6 @@ type SystemSettings struct { AdaptivePollingBaseInterval int `json:"adaptivePollingBaseInterval,omitempty"` AdaptivePollingMinInterval int `json:"adaptivePollingMinInterval,omitempty"` AdaptivePollingMaxInterval int `json:"adaptivePollingMaxInterval,omitempty"` - BackendPort int `json:"backendPort,omitempty"` FrontendPort int `json:"frontendPort,omitempty"` AllowedOrigins string `json:"allowedOrigins,omitempty"` ConnectionTimeout int `json:"connectionTimeout,omitempty"` diff --git a/pkg/server/server.go b/pkg/server/server.go index ae430c5cd..2515e8d8e 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -126,7 +126,7 @@ func Run(ctx context.Context, version string) error { defer cancel() // Metrics port is configurable via MetricsPort variable - metricsAddr := fmt.Sprintf("%s:%d", cfg.BackendHost, MetricsPort) + metricsAddr := fmt.Sprintf("%s:%d", cfg.BindAddress, MetricsPort) startMetricsServer(ctx, metricsAddr) // Initialize WebSocket hub first @@ -250,7 +250,7 @@ func Run(ctx context.Context, version string) error { // Create HTTP server with unified configuration srv := &http.Server{ - Addr: fmt.Sprintf("%s:%d", cfg.BackendHost, cfg.FrontendPort), + Addr: fmt.Sprintf("%s:%d", cfg.BindAddress, cfg.FrontendPort), Handler: router.Handler(), ReadHeaderTimeout: 15 * time.Second, WriteTimeout: 0, // Disabled to support SSE/streaming @@ -291,7 +291,7 @@ func Run(ctx context.Context, version string) error { go func() { if cfg.HTTPSEnabled && cfg.TLSCertFile != "" && cfg.TLSKeyFile != "" { log.Info(). - Str("host", cfg.BackendHost). + Str("host", cfg.BindAddress). Int("port", cfg.FrontendPort). Str("protocol", "HTTPS"). Msg("Server listening") @@ -303,7 +303,7 @@ func Run(ctx context.Context, version string) error { log.Warn().Msg("HTTPS_ENABLED is true but TLS_CERT_FILE or TLS_KEY_FILE not configured, falling back to HTTP") } log.Info(). - Str("host", cfg.BackendHost). + Str("host", cfg.BindAddress). Int("port", cfg.FrontendPort). Str("protocol", "HTTP"). Msg("Server listening") diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index ccd3ea90f..1fbb6def4 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -80,7 +80,7 @@ func TestServerRun_Shutdown(t *testing.T) { // Create a dummy config.yaml configFile := filepath.Join(tmpDir, "config.yaml") // Use 0 port to try to avoid conflicts, though Run() might default it. - if err := os.WriteFile(configFile, []byte("backendHost: 127.0.0.1\nfrontendPort: 0"), 0644); err != nil { + if err := os.WriteFile(configFile, []byte("bindAddress: 127.0.0.1\nfrontendPort: 0"), 0644); err != nil { t.Fatal(err) }