diff --git a/deploy/.env.example b/deploy/.env.example index 11a339e..d203a0a 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -14,6 +14,7 @@ JWT_SECRET=geo-web-Aa123456-change-me-in-production OPS_JWT_SECRET=geo-ops-Aa123456-change-me-in-production OPS_DEFAULT_ADMIN_PASSWORD=Aa123456 SCHEDULER_INTERNAL_METRICS_TOKEN=geo-scheduler-Aa123456-change-me-in-production +POSTGRES_PASSWORD=geo_dev # ─── Optional: MinIO credentials ───────────────────────────────────────────── MINIO_ROOT_USER=admin diff --git a/deploy/config.yaml b/deploy/config.yaml index ac316fc..308e51d 100644 --- a/deploy/config.yaml +++ b/deploy/config.yaml @@ -3,24 +3,24 @@ server: mode: release database: - host: postgres + host: pgbouncer port: 5432 user: geo - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} dbname: geo sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 12 + max_idle_conns: 3 monitoring_database: - host: monitoring-postgres + host: monitoring-pgbouncer port: 5432 user: geo - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} dbname: geo_monitoring sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 8 + max_idle_conns: 2 rabbitmq: url: amqp://geo:geo_dev@rabbitmq:5672/geo diff --git a/deploy/k3s/apps.yaml b/deploy/k3s/apps.yaml index 61c6ea7..096c7ed 100644 --- a/deploy/k3s/apps.yaml +++ b/deploy/k3s/apps.yaml @@ -38,6 +38,11 @@ spec: env: - name: CONFIG_PATH value: /app/configs/config.yaml + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD - name: TZ value: Asia/Shanghai - name: JWT_SECRET @@ -125,6 +130,11 @@ spec: env: - name: CONFIG_PATH value: /app/configs/config.yaml + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD - name: TZ value: Asia/Shanghai - name: JWT_SECRET @@ -193,6 +203,11 @@ spec: env: - name: CONFIG_PATH value: /app/configs/config.yaml + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD - name: TZ value: Asia/Shanghai - name: JWT_SECRET @@ -278,6 +293,11 @@ spec: env: - name: CONFIG_PATH value: /app/configs/config.yaml + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD - name: TZ value: Asia/Shanghai - name: SCHEDULER_HTTP_HOST @@ -384,6 +404,16 @@ spec: env: - name: CONFIG_PATH value: /app/configs/ops-config.yaml + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD + - name: OPS_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: geo-rankly-app-secret + key: POSTGRES_PASSWORD - name: TZ value: Asia/Shanghai - name: OPS_JWT_SECRET diff --git a/deploy/k3s/config/config.yaml b/deploy/k3s/config/config.yaml index 1d85641..ee4ecb0 100644 --- a/deploy/k3s/config/config.yaml +++ b/deploy/k3s/config/config.yaml @@ -3,24 +3,24 @@ server: mode: release database: - host: postgres + host: pgbouncer port: 5432 user: geo - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} dbname: geo sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 12 + max_idle_conns: 3 monitoring_database: - host: monitoring-postgres + host: monitoring-pgbouncer port: 5432 user: geo - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} dbname: geo_monitoring sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 8 + max_idle_conns: 2 rabbitmq: url: amqp://geo:geo_dev@rabbitmq:5672/geo diff --git a/deploy/k3s/config/ops-config.yaml b/deploy/k3s/config/ops-config.yaml index 77e9ae1..7d2cc50 100644 --- a/deploy/k3s/config/ops-config.yaml +++ b/deploy/k3s/config/ops-config.yaml @@ -3,23 +3,23 @@ server: mode: release database: - host: postgres + host: pgbouncer port: 5432 user: geo - password: geo_dev + password: ${OPS_POSTGRES_PASSWORD:geo_dev} dbname: geo sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 monitoring_database: - host: monitoring-postgres + host: monitoring-pgbouncer port: 5432 user: geo - password: geo_dev + password: ${OPS_POSTGRES_PASSWORD:geo_dev} dbname: geo_monitoring sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 redis: diff --git a/deploy/k3s/jobs.yaml b/deploy/k3s/jobs.yaml index b107c97..2197bbb 100644 --- a/deploy/k3s/jobs.yaml +++ b/deploy/k3s/jobs.yaml @@ -70,9 +70,10 @@ spec: - /bin/sh - -ec - | - /usr/local/bin/migrate -path /migrations -database "postgres://geo:${POSTGRES_PASSWORD}@postgres:5432/geo?sslmode=disable" up - /usr/local/bin/migrate -path /migrations_monitoring -database "postgres://geo:${POSTGRES_PASSWORD}@monitoring-postgres:5432/geo_monitoring?sslmode=disable" up - /usr/local/bin/migrate -path /migrations_ops -database "postgres://geo:${POSTGRES_PASSWORD}@postgres:5432/geo?sslmode=disable&x-migrations-table=schema_migrations_ops" up + export PGPASSWORD="${POSTGRES_PASSWORD}" + /usr/local/bin/migrate -path /migrations -database "postgres://geo@postgres:5432/geo?sslmode=disable" up + /usr/local/bin/migrate -path /migrations_monitoring -database "postgres://geo@monitoring-postgres:5432/geo_monitoring?sslmode=disable" up + /usr/local/bin/migrate -path /migrations_ops -database "postgres://geo@postgres:5432/geo?sslmode=disable&x-migrations-table=schema_migrations_ops" up /usr/local/bin/seed-platform-templates volumes: - name: app-config diff --git a/deploy/k3s/secrets.yaml b/deploy/k3s/secrets.yaml index 9924e3f..bb47f86 100644 --- a/deploy/k3s/secrets.yaml +++ b/deploy/k3s/secrets.yaml @@ -14,10 +14,10 @@ stringData: SCHEDULER_INTERNAL_METRICS_TOKEN: geo-metrics-token config.local.yaml: | database: - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} monitoring_database: - password: geo_dev + password: ${POSTGRES_PASSWORD:geo_dev} rabbitmq: url: amqp://geo:geo_dev@rabbitmq:5672/geo diff --git a/deploy/ops-config.yaml b/deploy/ops-config.yaml index 05dee13..538f734 100644 --- a/deploy/ops-config.yaml +++ b/deploy/ops-config.yaml @@ -3,23 +3,23 @@ server: mode: release database: - host: postgres + host: pgbouncer port: 5432 user: geo - password: geo_dev + password: ${OPS_POSTGRES_PASSWORD:geo_dev} dbname: geo sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 monitoring_database: - host: monitoring-postgres + host: monitoring-pgbouncer port: 5432 user: geo - password: geo_dev + password: ${OPS_POSTGRES_PASSWORD:geo_dev} dbname: geo_monitoring sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 redis: diff --git a/server/configs/config.local.yaml.example b/server/configs/config.local.yaml.example index 1c73c19..df86b80 100644 --- a/server/configs/config.local.yaml.example +++ b/server/configs/config.local.yaml.example @@ -11,6 +11,9 @@ database: user: geo password: geo_dev dbname: geo + sslmode: disable + max_open_conns: 12 + max_idle_conns: 3 monitoring_database: host: localhost @@ -19,8 +22,8 @@ monitoring_database: password: geo_dev dbname: geo_monitoring sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 8 + max_idle_conns: 2 rabbitmq: url: amqp://geo:geo_dev@localhost:5672/geo diff --git a/server/configs/config.yaml b/server/configs/config.yaml index fe11cb4..3f5ee7b 100644 --- a/server/configs/config.yaml +++ b/server/configs/config.yaml @@ -9,8 +9,8 @@ database: password: geo_dev dbname: geo sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 12 + max_idle_conns: 3 monitoring_database: host: localhost @@ -19,8 +19,8 @@ monitoring_database: password: geo_dev dbname: geo_monitoring sslmode: disable - max_open_conns: 25 - max_idle_conns: 5 + max_open_conns: 8 + max_idle_conns: 2 rabbitmq: url: amqp://geo:geo_dev@localhost:5672/geo diff --git a/server/configs/ops-config.yaml b/server/configs/ops-config.yaml index 213cae4..6b8314f 100644 --- a/server/configs/ops-config.yaml +++ b/server/configs/ops-config.yaml @@ -9,7 +9,7 @@ database: password: geo_dev dbname: geo sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 monitoring_database: @@ -19,7 +19,7 @@ monitoring_database: password: geo_dev dbname: geo_monitoring sslmode: disable - max_open_conns: 10 + max_open_conns: 5 max_idle_conns: 2 redis: diff --git a/server/internal/shared/config/config.go b/server/internal/shared/config/config.go index 1d9f9db..0a2374b 100644 --- a/server/internal/shared/config/config.go +++ b/server/internal/shared/config/config.go @@ -4,6 +4,8 @@ import ( "crypto/tls" "encoding/json" "fmt" + "net" + "net/url" "os" "strings" "time" @@ -53,8 +55,16 @@ type DatabaseConfig struct { } func (d DatabaseConfig) DSN() string { - return fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=%s", - d.User, d.Password, d.Host, d.Port, d.DBName, d.SSLMode) + u := url.URL{ + Scheme: "postgres", + User: url.UserPassword(d.User, d.Password), + Host: net.JoinHostPort(d.Host, fmt.Sprintf("%d", d.Port)), + Path: "/" + d.DBName, + } + q := u.Query() + q.Set("sslmode", d.SSLMode) + u.RawQuery = q.Encode() + return u.String() } type RedisConfig struct { diff --git a/server/internal/shared/config/config_test.go b/server/internal/shared/config/config_test.go index 7313776..69ab83f 100644 --- a/server/internal/shared/config/config_test.go +++ b/server/internal/shared/config/config_test.go @@ -27,6 +27,23 @@ llm: } } +func TestDatabaseConfigDSNEscapesCredentials(t *testing.T) { + cfg := DatabaseConfig{ + Host: "db.internal", + Port: 5432, + User: "geo", + Password: "p@ss:word/with?symbols", + DBName: "geo", + SSLMode: "disable", + } + + got := cfg.DSN() + want := "postgres://geo:p%40ss%3Aword%2Fwith%3Fsymbols@db.internal:5432/geo?sslmode=disable" + if got != want { + t.Fatalf("DSN() = %q, want %q", got, want) + } +} + func TestLoadFallsBackToConfigLLMAPIKey(t *testing.T) { t.Setenv("LLM_API_KEY", "")