mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-02 04:20:50 +08:00
feat(server): Add cloud deploy mode
This commit is contained in:
@@ -96,6 +96,14 @@ func main() {
|
|||||||
var err error
|
var err error
|
||||||
var cfg *config.Config
|
var cfg *config.Config
|
||||||
var wd string
|
var wd string
|
||||||
|
var isCloudDeploy bool
|
||||||
|
|
||||||
|
// Check for cloud deploy mode only on first execution
|
||||||
|
// Read env var name in uppercase: DEPLOY
|
||||||
|
deployEnv := os.Getenv("DEPLOY")
|
||||||
|
if deployEnv == "cloud" {
|
||||||
|
isCloudDeploy = true
|
||||||
|
}
|
||||||
|
|
||||||
// Determine and load the configuration file.
|
// Determine and load the configuration file.
|
||||||
// If a config path is provided via flags, it is used directly.
|
// If a config path is provided via flags, it is used directly.
|
||||||
@@ -103,18 +111,31 @@ func main() {
|
|||||||
var configFilePath string
|
var configFilePath string
|
||||||
if configPath != "" {
|
if configPath != "" {
|
||||||
configFilePath = configPath
|
configFilePath = configPath
|
||||||
cfg, err = config.LoadConfig(configPath)
|
cfg, err = config.LoadConfigOptional(configPath, isCloudDeploy)
|
||||||
} else {
|
} else {
|
||||||
wd, err = os.Getwd()
|
wd, err = os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to get working directory: %v", err)
|
log.Fatalf("failed to get working directory: %v", err)
|
||||||
}
|
}
|
||||||
configFilePath = filepath.Join(wd, "config.yaml")
|
configFilePath = filepath.Join(wd, "config.yaml")
|
||||||
cfg, err = config.LoadConfig(configFilePath)
|
cfg, err = config.LoadConfigOptional(configFilePath, isCloudDeploy)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to load config: %v", err)
|
log.Fatalf("failed to load config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log if we're running without a config file in cloud deploy mode
|
||||||
|
var configFileExists bool
|
||||||
|
if isCloudDeploy {
|
||||||
|
if _, err = os.Stat(configFilePath); os.IsNotExist(err) {
|
||||||
|
// Don't mislead: API server will not start until configuration is provided.
|
||||||
|
log.Info("Cloud deploy mode: No configuration file detected; standing by for configuration (API server not started)")
|
||||||
|
configFileExists = false
|
||||||
|
} else {
|
||||||
|
log.Info("Cloud deploy mode: Configuration file detected; starting service")
|
||||||
|
configFileExists = true
|
||||||
|
}
|
||||||
|
}
|
||||||
usage.SetStatisticsEnabled(cfg.UsageStatisticsEnabled)
|
usage.SetStatisticsEnabled(cfg.UsageStatisticsEnabled)
|
||||||
|
|
||||||
if err = logging.ConfigureLogOutput(cfg.LoggingToFile); err != nil {
|
if err = logging.ConfigureLogOutput(cfg.LoggingToFile); err != nil {
|
||||||
@@ -161,6 +182,12 @@ func main() {
|
|||||||
} else if geminiWebAuth {
|
} else if geminiWebAuth {
|
||||||
cmd.DoGeminiWebAuth(cfg)
|
cmd.DoGeminiWebAuth(cfg)
|
||||||
} else {
|
} else {
|
||||||
|
// In cloud deploy mode without config file, just wait for shutdown signals
|
||||||
|
if isCloudDeploy && !configFileExists {
|
||||||
|
// No config file available, just wait for shutdown
|
||||||
|
cmd.WaitForCloudDeploy()
|
||||||
|
return
|
||||||
|
}
|
||||||
// Start the main proxy service
|
// Start the main proxy service
|
||||||
cmd.StartService(cfg, configFilePath, password)
|
cmd.StartService(cfg, configFilePath, password)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ services:
|
|||||||
COMMIT: ${COMMIT:-none}
|
COMMIT: ${COMMIT:-none}
|
||||||
BUILD_DATE: ${BUILD_DATE:-unknown}
|
BUILD_DATE: ${BUILD_DATE:-unknown}
|
||||||
container_name: cli-proxy-api
|
container_name: cli-proxy-api
|
||||||
|
environment:
|
||||||
|
DEPLOY: ${DEPLOY:-}
|
||||||
ports:
|
ports:
|
||||||
- "8317:8317"
|
- "8317:8317"
|
||||||
- "8085:8085"
|
- "8085:8085"
|
||||||
|
|||||||
@@ -53,3 +53,17 @@ func StartService(cfg *config.Config, configPath string, localPassword string) {
|
|||||||
log.Fatalf("proxy service exited with error: %v", err)
|
log.Fatalf("proxy service exited with error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WaitForCloudDeploy waits indefinitely for shutdown signals in cloud deploy mode
|
||||||
|
// when no configuration file is available.
|
||||||
|
func WaitForCloudDeploy() {
|
||||||
|
// Clarify that we are intentionally idle for configuration and not running the API server.
|
||||||
|
log.Info("Cloud deploy mode: No config found; standing by for configuration. API server is not started. Press Ctrl+C to exit.")
|
||||||
|
|
||||||
|
ctxSignal, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Block until shutdown signal is received
|
||||||
|
<-ctxSignal.Done()
|
||||||
|
log.Info("Cloud deploy mode: Shutdown signal received; exiting")
|
||||||
|
}
|
||||||
|
|||||||
@@ -187,9 +187,19 @@ type OpenAICompatibilityModel struct {
|
|||||||
// - *Config: The loaded configuration
|
// - *Config: The loaded configuration
|
||||||
// - error: An error if the configuration could not be loaded
|
// - error: An error if the configuration could not be loaded
|
||||||
func LoadConfig(configFile string) (*Config, error) {
|
func LoadConfig(configFile string) (*Config, error) {
|
||||||
|
return LoadConfigOptional(configFile, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfigOptional reads YAML from configFile.
|
||||||
|
// If optional is true and the file is missing, it returns an empty Config.
|
||||||
|
func LoadConfigOptional(configFile string, optional bool) (*Config, error) {
|
||||||
// Read the entire configuration file into memory.
|
// Read the entire configuration file into memory.
|
||||||
data, err := os.ReadFile(configFile)
|
data, err := os.ReadFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if optional && os.IsNotExist(err) {
|
||||||
|
// Missing and optional: return empty config.
|
||||||
|
return &Config{}, nil
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("failed to read config file: %w", err)
|
return nil, fmt.Errorf("failed to read config file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user