config.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package config
  2. import (
  3. "os"
  4. "strings"
  5. "github.com/joho/godotenv"
  6. )
  7. type Config struct {
  8. AppEnv string
  9. ServerPort string
  10. DatabaseURL string
  11. RedisURL string
  12. S3Endpoint string
  13. S3PublicEndpoint string
  14. S3AccessKey string
  15. S3SecretKey string
  16. S3Bucket string
  17. JWTSecret string
  18. JWTRefreshSecret string
  19. CloudPaymentsPublicID string
  20. CloudPaymentsAPISecret string
  21. AllowedOrigins []string
  22. }
  23. func Load() *Config {
  24. godotenv.Load()
  25. cfg := &Config{
  26. AppEnv: getEnv("APP_ENV", "development"),
  27. ServerPort: getEnv("SERVER_PORT", "8080"),
  28. DatabaseURL: buildDatabaseURL(),
  29. RedisURL: buildRedisURL(),
  30. S3Endpoint: getEnv("S3_ENDPOINT", "http://localhost:9000"),
  31. S3PublicEndpoint: getEnv("S3_PUBLIC_ENDPOINT", "http://localhost:9000"),
  32. S3AccessKey: getEnv("S3_ACCESS_KEY", "photoplaces"),
  33. S3SecretKey: getSecret("S3_SECRET_KEY", "photoplaces_dev"),
  34. S3Bucket: getEnv("S3_BUCKET", "photoplaces"),
  35. JWTSecret: getSecret("JWT_SECRET", "dev-secret"),
  36. JWTRefreshSecret: getSecret("JWT_REFRESH_SECRET", "dev-refresh-secret"),
  37. CloudPaymentsPublicID: getEnv("CLOUDPAYMENTS_PUBLIC_ID", ""),
  38. CloudPaymentsAPISecret: getEnv("CLOUDPAYMENTS_API_SECRET", ""),
  39. AllowedOrigins: strings.Split(getEnv("ALLOWED_ORIGINS", "http://localhost:3000"), ","),
  40. }
  41. return cfg
  42. }
  43. func getEnv(key, fallback string) string {
  44. if v := os.Getenv(key); v != "" {
  45. return v
  46. }
  47. return fallback
  48. }
  49. func getSecret(key, fallback string) string {
  50. // Try _FILE variant first (Docker secrets)
  51. if v := os.Getenv(key + "_FILE"); v != "" {
  52. content, err := os.ReadFile(v)
  53. if err == nil {
  54. return strings.TrimSpace(string(content))
  55. }
  56. }
  57. // Fallback to env var
  58. if v := os.Getenv(key); v != "" {
  59. return v
  60. }
  61. return fallback
  62. }
  63. func buildDatabaseURL() string {
  64. // If DATABASE_URL is explicitly set, use it
  65. if v := os.Getenv("DATABASE_URL"); v != "" {
  66. return v
  67. }
  68. // Build from components with secret from file
  69. password := getSecret("DB_PASSWORD", "photoplaces_dev")
  70. return "postgres://photoplaces:" + password + "@postgres:5432/photoplaces?sslmode=disable"
  71. }
  72. func buildRedisURL() string {
  73. if v := os.Getenv("REDIS_URL"); v != "" {
  74. return v
  75. }
  76. password := getSecret("REDIS_PASSWORD", "")
  77. if password != "" {
  78. return "redis://:" + password + "@redis:6379/0"
  79. }
  80. return "redis://redis:6379/0"
  81. }