diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index b3b2a96..ee679ec 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -2,29 +2,40 @@ package config import ( "log" + "os" "github.com/spf13/viper" ) -// Init 初始化配置 +var dataDir = "/app/data" + func Init() { + if dir := os.Getenv("DATA_DIR"); dir != "" { + dataDir = dir + } + if _, err := os.Stat(dataDir); os.IsNotExist(err) { + os.MkdirAll(dataDir, 0755) + } + viper.SetConfigName("config") viper.SetConfigType("yaml") + viper.AddConfigPath(dataDir) viper.AddConfigPath(".") viper.AddConfigPath("./config") - // 设置默认值 setDefaults() - // 读取配置文件 if err := viper.ReadInConfig(); err != nil { log.Printf("Warning: Config file not found, using defaults: %v", err) } - // 环境变量覆盖 viper.AutomaticEnv() } +func GetDataDir() string { + return dataDir +} + // setDefaults 设置默认配置值 func setDefaults() { // 应用配置 diff --git a/backend/internal/database/database.go b/backend/internal/database/database.go index 3654162..5b3c872 100644 --- a/backend/internal/database/database.go +++ b/backend/internal/database/database.go @@ -11,7 +11,6 @@ import ( "context" "fmt" "log" - "os" "path/filepath" "time" "verification-platform-backend/internal/config" @@ -52,26 +51,18 @@ func initDatabase() { } func initSQLite() { - dbPath := "verification_platform.db" - absPath, err := filepath.Abs(dbPath) - if err != nil { - log.Fatal("Failed to get absolute path:", err.Error()) - } - - wd, err := os.Getwd() - if err == nil && filepath.Base(wd) == "cmd" { - absPath = filepath.Join(filepath.Dir(wd), "verification_platform.db") - } + dataDir := config.GetDataDir() + dbPath := filepath.Join(dataDir, "verification_platform.db") var errOpen error - DB, errOpen = gorm.Open(sqlite.Open(absPath), &gorm.Config{ + DB, errOpen = gorm.Open(sqlite.Open(dbPath), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), DisableForeignKeyConstraintWhenMigrating: true, }) if errOpen != nil { log.Fatal("Failed to create SQLite database:", errOpen.Error()) } - log.Printf("Using SQLite database: %s\n", absPath) + log.Printf("Using SQLite database: %s\n", dbPath) if sqlDB, err := DB.DB(); err == nil { sqlDB.SetMaxIdleConns(10) @@ -132,27 +123,19 @@ func initAutoDetect() { }) if err != nil { - log.Println("Failed to connect to MySQL, using SQLite database for development:", err.Error()) + log.Println("Failed to connect to MySQL, using SQLite database:", err.Error()) - dbPath := "verification_platform.db" - absPath, err := filepath.Abs(dbPath) - if err != nil { - log.Fatal("Failed to get absolute path:", err.Error()) - } + dataDir := config.GetDataDir() + dbPath := filepath.Join(dataDir, "verification_platform.db") - wd, err := os.Getwd() - if err == nil && filepath.Base(wd) == "cmd" { - absPath = filepath.Join(filepath.Dir(wd), "verification_platform.db") - } - - DB, err = gorm.Open(sqlite.Open(absPath), &gorm.Config{ + DB, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), DisableForeignKeyConstraintWhenMigrating: true, }) if err != nil { log.Fatal("Failed to create SQLite database:", err.Error()) } - log.Printf("Database file path: %s\n", absPath) + log.Printf("Using SQLite database: %s\n", dbPath) } if sqlDB, err := DB.DB(); err == nil { diff --git a/backend/internal/router/install/install.go b/backend/internal/router/install/install.go index ed4c4f3..66a2eff 100644 --- a/backend/internal/router/install/install.go +++ b/backend/internal/router/install/install.go @@ -80,9 +80,9 @@ func handleTestDatabase(c *gin.Context) { } if req.DbType == "sqlite" { - dbPath := "verification_platform.db" - absPath, _ := filepath.Abs(dbPath) - testDB, err := gorm.Open(sqlite.Open(absPath), &gorm.Config{ + dataDir := config.GetDataDir() + dbPath := filepath.Join(dataDir, "verification_platform.db") + testDB, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { @@ -167,9 +167,9 @@ func handleSetup(c *gin.Context) { var err error if req.DbType == "sqlite" { - dbPath := "verification_platform.db" - absPath, _ := filepath.Abs(dbPath) - newDB, err = gorm.Open(sqlite.Open(absPath), &gorm.Config{ + dataDir := config.GetDataDir() + dbPath := filepath.Join(dataDir, "verification_platform.db") + newDB, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), DisableForeignKeyConstraintWhenMigrating: true, }) @@ -241,6 +241,11 @@ func handleSetup(c *gin.Context) { } func checkConfigFile() bool { + dataDir := config.GetDataDir() + configPath := filepath.Join(dataDir, "config.yaml") + if _, err := os.Stat(configPath); err == nil { + return true + } paths := []string{"config.yaml", "./config/config.yaml"} for _, p := range paths { if _, err := os.Stat(p); err == nil { @@ -338,7 +343,9 @@ func generateConfigFile(dbType string, req SetupRequest, jwtSecret string) strin } func saveConfigFile(content string) error { - file, err := os.Create("config.yaml") + dataDir := config.GetDataDir() + configPath := filepath.Join(dataDir, "config.yaml") + file, err := os.Create(configPath) if err != nil { return err } diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index a2ec7b2..d0aff57 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,4 +1,16 @@ services: + app: + image: ghcr.io/cmakecpp/verify:main + container_name: verify-app + restart: unless-stopped + ports: + - "${APP_PORT:-8080}:8080" + volumes: + - app_data:/app/data + - uploads:/app/uploads + networks: + - verify-network + mysql: image: mysql:8.0 container_name: verify-mysql @@ -8,42 +20,13 @@ services: MYSQL_DATABASE: ${MYSQL_DATABASE:-verification_platform} MYSQL_CHARACTER_SET_SERVER: utf8mb4 MYSQL_COLLATION_SERVER: utf8mb4_unicode_ci - ports: - - "${MYSQL_PORT:-3306}:3306" volumes: - mysql_data:/var/lib/mysql networks: - verify-network - healthcheck: - test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] - interval: 10s - timeout: 5s - retries: 5 - - app: - image: ghcr.io/cmakecpp/verify:main - container_name: verify-app - restart: unless-stopped - environment: - - APP_ENV=production - - APP_PORT=8080 - - APP_JWT_SECRET=${JWT_SECRET:-your-jwt-secret-change-me} - - DATABASE_HOST=mysql - - DATABASE_PORT=3306 - - DATABASE_NAME=${MYSQL_DATABASE:-verification_platform} - - DATABASE_USERNAME=root - - DATABASE_PASSWORD=${MYSQL_ROOT_PASSWORD:-root123456} - ports: - - "${APP_PORT:-8080}:8080" - volumes: - - uploads:/app/uploads - depends_on: - mysql: - condition: service_healthy - networks: - - verify-network volumes: + app_data: mysql_data: uploads: