fix(server): Read database config directly from environment variables

This commit is contained in:
2025-04-18 22:01:20 +02:00
parent b999cb5832
commit 0f68084f49
8 changed files with 182 additions and 6 deletions
+12
View File
@@ -22,4 +22,16 @@ dependencies {
testImplementation(libs.jupiter.junit.jupiter)
implementation(libs.ktor.server.config.yaml)
testImplementation(libs.junit.junit.jupiter)
// Exposed für Datenbankzugriff (Core, DAO-Pattern, JDBC-Implementierung)
implementation(libs.exposed.core)
implementation(libs.exposed.dao)
implementation(libs.exposed.jdbc)
// JDBC Treiber für PostgreSQL (nur zur Laufzeit benötigt)
runtimeOnly(libs.postgresql.driver)
// HikariCP für Connection Pooling
implementation(libs.hikari.cp)
}
@@ -1,5 +1,6 @@
package at.mocode
import at.mocode.plugins.configureDatabase
import io.ktor.server.application.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
@@ -10,6 +11,11 @@ fun main(args: Array<String>) {
}
fun Application.module() {
// Als Erstes die Datenbank konfigurieren:
configureDatabase()
// Danach deine anderen Konfigurationen (Routing etc.):
routing {
get("/") {
call.respondText("Ktor: ${Greeting().greet()}")
@@ -0,0 +1,68 @@
package at.mocode.plugins
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.ktor.server.application.*
import org.jetbrains.exposed.sql.Database
import org.slf4j.LoggerFactory
fun Application.configureDatabase() {
val log = LoggerFactory.getLogger("DatabaseInitialization")
log.info("Initializing database connection from environment variables...")
// Lese Konfiguration direkt aus Umgebungsvariablen,
// die von Docker Compose (aus .env) gesetzt werden.
val dbHost = System.getenv("DB_HOST") ?: "db" // Fallback auf 'db', falls nicht gesetzt
val dbPort = System.getenv("DB_PORT") ?: "5432"
val dbName = System.getenv("DB_NAME")
?: error("Database name (DB_NAME) not set in environment") // Fehler, wenn nicht gesetzt
val dbUser = System.getenv("DB_USER")
?: error("Database user (DB_USER) not set in environment") // Fehler, wenn nicht gesetzt
val dbPassword = System.getenv("DB_PASSWORD")
?: error("Database password (DB_PASSWORD) not set in environment") // Fehler, wenn nicht gesetzt
val driverClassName = "org.postgresql.Driver" // Ist für Postgres fix
// Pool Size auch optional aus Env Var lesen
val maxPoolSize = System.getenv("DB_POOL_SIZE")?.toIntOrNull() ?: 10
// Baue die JDBC URL zusammen
val jdbcURL = "jdbc:postgresql://$dbHost:$dbPort/$dbName"
log.info("Attempting to connect to database at URL: {}", jdbcURL) // Logge die URL (ohne User/Passwort!)
// Konfiguriere HikariCP mit den Werten aus der Umgebung
val hikariConfig = HikariConfig().apply {
this.driverClassName = driverClassName
this.jdbcUrl = jdbcURL
this.username = dbUser
this.password = dbPassword
this.maximumPoolSize = maxPoolSize
// Hier könnten weitere HikariCP-Optimierungen hin
try {
this.validate() // Prüft die Konfiguration frühzeitig
} catch (e: Exception) {
log.error("HikariCP configuration validation failed!", e)
throw e // Wirft den Fehler weiter, damit die App nicht startet
}
}
// Erstelle DataSource und verbinde Exposed
try {
val dataSource = HikariDataSource(hikariConfig)
Database.connect(dataSource)
log.info("Database connection pool initialized successfully!")
} catch (e: Exception) {
log.error("Failed to initialize database connection pool!", e)
// Optional: Hier entscheiden, ob die App trotzdem starten soll oder nicht.
// Aktuell würde sie bei Fehlern hier abstürzen (was oft gewünscht ist).
throw e
}
// --- TODO für den NÄCHSTEN Schritt ---
// Hier kommt später die Logik zum Erstellen der Tabellen hin,
// z.B. innerhalb einer Transaktion:
// transaction {
// SchemaUtils.create(TurniereTable) // Erstellt die Tabelle, wenn sie nicht existiert
// }
// ------------------------------------
}
+1 -6
View File
@@ -1,5 +1,4 @@
# Grundkonfiguration für Ktor in YAML
ktor:
deployment:
# Der Port, auf dem der Server lauschen soll
@@ -9,11 +8,7 @@ ktor:
# watch:
# - classes
# - resources
application:
# Hier wird Ktor gesagt, welche Funktion die Konfiguration enthält
# PASSE DEN PFAD AN, falls deine Application.kt oder module() anders heißt/liegt!
modules:
- at.mocode.ApplicationKt.module
# Wenn Application.kt direkt unter at.mocode liegt:
# - at.mocode.ApplicationKt.module
- at.mocode.ApplicationKt.module