数据库+redis+meilisearch+s3+EQURL 配置全部走环境变量,不在代码层硬编码

This commit is contained in:
eafonyang
2026-07-13 14:16:05 +08:00
parent c1547f9a8f
commit 4f1da3675b
9 changed files with 80 additions and 215 deletions
+31 -20
View File
@@ -1,35 +1,46 @@
# Server
APP_ENV=development
APP_ENV=production
APP_HOST=0.0.0.0
APP_PORT=8080
# Gin mode: debug | release | test
GIN_MODE=debug
GIN_MODE=release
# Database (development reads from env, default host 192.168.9.127)
DATABASE_HOST=192.168.9.127
# Database
DATABASE_HOST=database-1.chmuueamo72p.eu-central-1.rds.amazonaws.com
DATABASE_PORT=3306
DATABASE_NAME=audio
DATABASE_USER=root
DATABASE_PASSWORD=root123
DATABASE_PASSWORD="young9#!UJsD219921031"
# Meilisearch (development defaults apply when APP_ENV=development and vars are unset)
# MEILISEARCH_HOST=http://ec2-18-184-205-87.eu-central-1.compute.amazonaws.com:7700
# MEILISEARCH_API_KEY=your-api-key
# MEILISEARCH_INDEX=models
# Meilisearch
MEILISEARCH_HOST=http://ip-172-31-13-240.eu-central-1.compute.internal:7700
MEILISEARCH_API_KEY="young9#!UJsD219921031"
MEILISEARCH_INDEX=models
# Redis (development reads from env, default host 192.168.9.127)
REDIS_HOST=192.168.9.127
# Redis
REDIS_HOST=172.31.13.240
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_PASSWORD=eafon123!
REDIS_DATABASE=1
# Share code TTL (bare number = minutes; suffix: m/h/d), e.g. 30, 30m, 24h, 30d
SHARE_CODE_TTL_MIN=30
# SHARE_CODE_MAX_PER_MAC=1
# Equalize API
EQ_API_URL=http://172.31.18.70:8000/equalize
EQ_EXTERNAL_API_URL=https://autoeq.app/equalize
# S3 (local development only; production uses EC2 IAM role)
# AWS_REGION=eu-central-1
# S3_BUCKET=luxsin-app-bucket
# AWS_ACCESS_KEY_ID=your-access-key-id
# AWS_SECRET_ACCESS_KEY=your-secret-access-key
# Share code TTL (bare number = minutes; suffix: m/h/d), e.g. 30, 30m, 24h, 30d
#一个用户在有效期内至多可以创建多少个分享码
SHARE_CODE_MAX_PER_MAC=10
#分享码有效期
SHARE_CODE_TTL_MIN=30d
# S3 (生产环境使用 EC2 IAM role 时,可不设置 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)
AWS_REGION=eu-central-1
S3_BUCKET=luxsin-app-bucket
AWS_ACCESS_KEY_ID=AKIAVMFK45I6P3TNI3VJ
AWS_SECRET_ACCESS_KEY=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
# Persist tasks
ENABLE_PERSIST_TASK=false
ENABLE_IMPEDANCE_PERSIST_TASK=false
-19
View File
@@ -1,19 +0,0 @@
APP_ENV=production
APP_HOST=0.0.0.0
APP_PORT=8080
GIN_MODE=release
# Production uses built-in RDS host when DATABASE_HOST is unset.
# Password must be set via environment variable (never commit real password).
# jdbc:mysql://database-1.chmuueamo72p.eu-central-1.rds.amazonaws.com:3306/audio?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=Asia/Shanghai
# young9#!UJsD219921031
# root
DATABASE_PASSWORD=your-production-password
# S3 (uses EC2 IAM role; do not set access keys in production)
AWS_REGION=eu-central-1
S3_BUCKET=luxsin-app-bucket
# Share code TTL (bare number = minutes; suffix: m/h/d), e.g. 30, 30m, 24h, 30d
SHARE_CODE_TTL_MIN=30
+2 -13
View File
@@ -7,19 +7,8 @@ services:
restart: always
ports:
- "8084:8080"
environment:
- APP_ENV=production
- APP_HOST=0.0.0.0
- APP_PORT=8080
- DATABASE_PASSWORD=${DATABASE_PASSWORD}
- REDIS_PASSWORD=${REDIS_PASSWORD:-eafon123!}
- MEILISEARCH_API_KEY=${MEILISEARCH_API_KEY:-young9#!UJsD219921031}
- ENABLE_PERSIST_TASK=false
- ENABLE_IMPEDANCE_PERSIST_TASK=false
- AWS_REGION=eu-central-1
- S3_BUCKET=luxsin-app-bucket
- SHARE_CODE_MAX_PER_MAC=${SHARE_CODE_MAX_PER_MAC:-1}
- SHARE_CODE_TTL_MIN=${SHARE_CODE_TTL_MIN:-30}
env_file:
- .env
healthcheck:
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:8080/api/v1/health"]
interval: 30s
+6 -6
View File
@@ -30,26 +30,26 @@ func Load() (*Config, error) {
env := getEnv("APP_ENV", "development")
db, err := loadDatabase(env)
db, err := loadDatabase()
if err != nil {
return nil, err
}
if err := db.validate(env); err != nil {
if err := db.validate(); err != nil {
return nil, err
}
ms := loadMeilisearch(env)
ms := loadMeilisearch()
if err := ms.validate(); err != nil {
return nil, err
}
rd := loadRedis(env)
rd := loadRedis()
if err := rd.validate(); err != nil {
return nil, err
}
eq := loadEqualize(env)
s3cfg := loadS3(env)
eq := loadEqualize()
s3cfg := loadS3()
shareCodeTTL, err := parseShareCodeTTL(getEnv("SHARE_CODE_TTL_MIN", "30"))
if err != nil {
+4 -37
View File
@@ -2,7 +2,6 @@ package config
import (
"fmt"
"os"
"strconv"
)
@@ -14,50 +13,21 @@ type DatabaseConfig struct {
Password string
}
func loadDatabase(env string) (DatabaseConfig, error) {
switch env {
case "production":
if os.Getenv("DATABASE_HOST") != "" {
return databaseFromEnv()
}
return DatabaseConfig{
Host: "database-1.chmuueamo72p.eu-central-1.rds.amazonaws.com",
Port: 3306,
Name: "audio",
User: "root",
Password: os.Getenv("DATABASE_PASSWORD"),
}, nil
default:
func loadDatabase() (DatabaseConfig, error) {
port, err := strconv.Atoi(getEnv("DATABASE_PORT", "3306"))
if err != nil {
return DatabaseConfig{}, fmt.Errorf("invalid DATABASE_PORT: %w", err)
}
return DatabaseConfig{
Host: getEnv("DATABASE_HOST", "192.168.9.127"),
Host: getEnv("DATABASE_HOST", ""),
Port: port,
Name: getEnv("DATABASE_NAME", "audio"),
User: getEnv("DATABASE_USER", "root"),
Password: getEnv("DATABASE_PASSWORD", "root123"),
}, nil
}
}
func databaseFromEnv() (DatabaseConfig, error) {
port, err := strconv.Atoi(getEnv("DATABASE_PORT", "3306"))
if err != nil {
return DatabaseConfig{}, fmt.Errorf("invalid DATABASE_PORT: %w", err)
}
return DatabaseConfig{
Host: os.Getenv("DATABASE_HOST"),
Port: port,
Name: getEnv("DATABASE_NAME", "audio"),
User: getEnv("DATABASE_USER", "root"),
Password: os.Getenv("DATABASE_PASSWORD"),
Password: getEnv("DATABASE_PASSWORD", ""),
}, nil
}
func (d DatabaseConfig) validate(env string) error {
func (d DatabaseConfig) validate() error {
if d.Host == "" {
return fmt.Errorf("database host is required")
}
@@ -67,8 +37,5 @@ func (d DatabaseConfig) validate(env string) error {
if d.User == "" {
return fmt.Errorf("database user is required")
}
if env == "production" && d.Password == "" {
return fmt.Errorf("DATABASE_PASSWORD is required in production")
}
return nil
}
+3 -23
View File
@@ -1,33 +1,13 @@
package config
import "os"
const defaultExternalEQAPIURL = "https://autoeq.app/equalize"
type EqualizeConfig struct {
APIURL string // 内网 EQ 接口(正式环境 Eafonyoung 源使用)
ExternalAPIURL string // 公网 EQ 接口(正式环境非 Eafonyoung 源使用)
}
func loadEqualize(env string) EqualizeConfig {
external := getEnv("EQ_EXTERNAL_API_URL", defaultExternalEQAPIURL)
if os.Getenv("EQ_API_URL") != "" {
func loadEqualize() EqualizeConfig {
return EqualizeConfig{
APIURL: os.Getenv("EQ_API_URL"),
ExternalAPIURL: external,
}
}
switch env {
case "production":
return EqualizeConfig{
APIURL: "http://172.31.18.70:8000/equalize",
ExternalAPIURL: external,
}
default:
return EqualizeConfig{
APIURL: defaultExternalEQAPIURL,
ExternalAPIURL: external,
}
APIURL: getEnv("EQ_API_URL", ""),
ExternalAPIURL: getEnv("EQ_EXTERNAL_API_URL", "https://autoeq.app/equalize"),
}
}
+3 -21
View File
@@ -2,7 +2,6 @@ package config
import (
"fmt"
"os"
)
type MeilisearchConfig struct {
@@ -11,29 +10,12 @@ type MeilisearchConfig struct {
Index string
}
func loadMeilisearch(env string) MeilisearchConfig {
if os.Getenv("MEILISEARCH_HOST") != "" {
func loadMeilisearch() MeilisearchConfig {
return MeilisearchConfig{
Host: os.Getenv("MEILISEARCH_HOST"),
APIKey: os.Getenv("MEILISEARCH_API_KEY"),
Host: getEnv("MEILISEARCH_HOST", ""),
APIKey: getEnv("MEILISEARCH_API_KEY", ""),
Index: getEnv("MEILISEARCH_INDEX", "models"),
}
}
switch env {
case "production":
return MeilisearchConfig{
Host: "http://ip-172-31-22-170.eu-central-1.compute.internal:7700",
APIKey: getEnv("MEILISEARCH_API_KEY", "young9#!UJsD219921031"),
Index: "models",
}
default:
return MeilisearchConfig{
Host: "http://ec2-18-184-205-87.eu-central-1.compute.amazonaws.com:7700",
APIKey: getEnv("MEILISEARCH_API_KEY", "young9#!UJsD219921031"),
Index: "models",
}
}
}
func (m MeilisearchConfig) validate() error {
+2 -28
View File
@@ -2,7 +2,6 @@ package config
import (
"fmt"
"os"
"strconv"
)
@@ -13,40 +12,15 @@ type RedisConfig struct {
Database int
}
func loadRedis(env string) RedisConfig {
switch env {
case "production":
if os.Getenv("REDIS_HOST") != "" {
return redisFromEnv("16279")
}
return RedisConfig{
Host: "172.31.38.162",
Port: 16279,
Password: getEnv("REDIS_PASSWORD", "eafon123!"),
Database: 1,
}
default:
func loadRedis() RedisConfig {
port, _ := strconv.Atoi(getEnv("REDIS_PORT", "6379"))
db, _ := strconv.Atoi(getEnv("REDIS_DATABASE", "1"))
return RedisConfig{
Host: getEnv("REDIS_HOST", "192.168.9.127"),
Host: getEnv("REDIS_HOST", ""),
Port: port,
Password: getEnv("REDIS_PASSWORD", ""),
Database: db,
}
}
}
func redisFromEnv(defaultPort string) RedisConfig {
port, _ := strconv.Atoi(getEnv("REDIS_PORT", defaultPort))
db, _ := strconv.Atoi(getEnv("REDIS_DATABASE", "1"))
return RedisConfig{
Host: os.Getenv("REDIS_HOST"),
Port: port,
Password: os.Getenv("REDIS_PASSWORD"),
Database: db,
}
}
func (r RedisConfig) validate() error {
+4 -23
View File
@@ -1,7 +1,5 @@
package config
import "os"
type S3Config struct {
Bucket string
Region string
@@ -9,28 +7,11 @@ type S3Config struct {
SecretAccessKey string
}
func loadS3(env string) S3Config {
if os.Getenv("AWS_ACCESS_KEY_ID") != "" || os.Getenv("AWS_SECRET_ACCESS_KEY") != "" {
func loadS3() S3Config {
return S3Config{
Bucket: getEnv("S3_BUCKET", "luxsin-app-bucket"),
Bucket: getEnv("S3_BUCKET", ""),
Region: getEnv("AWS_REGION", "eu-central-1"),
AccessKeyID: os.Getenv("AWS_ACCESS_KEY_ID"),
SecretAccessKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
}
}
switch env {
case "production":
return S3Config{
Bucket: getEnv("S3_BUCKET", "luxsin-app-bucket"),
Region: getEnv("AWS_REGION", "eu-central-1"),
}
default:
return S3Config{
Bucket: getEnv("S3_BUCKET", "luxsin-app-bucket"),
Region: getEnv("AWS_REGION", "eu-central-1"),
AccessKeyID: "AKIAVMFK45I6P3TNI3VJ",
SecretAccessKey: "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",
}
AccessKeyID: getEnv("AWS_ACCESS_KEY_ID", ""),
SecretAccessKey: getEnv("AWS_SECRET_ACCESS_KEY", ""),
}
}