[Ktor] Ktor에서 Docker를 이용하여 PostgreSQL 연동하기

밤새·2024년 8월 15일
0

Back/Front

목록 보기
11/12
post-thumbnail

Ktor에서 Docker를 이용하여 PostgreSQL 연동하는 과정에 대한 글입니다!
프로젝트 생성 방법은 이 글을 참고해주세요!
준비물 : Docker Desktop, Ktor 프로젝트

1. Docker에서 PostgreSQL 실행

먼저, PostgreSQL Docker 이미지를 풀받고 컨테이너를 실행합니다. 기본적으로 Docker Hub에 있는 postgres 이미지를 사용하겠습니다.

1.1. PostgreSQL Docker 이미지 풀받기 및 컨테이너 실행

터미널에서 아래 명령어를 실행하여 PostgreSQL Docker 컨테이너를 시작합니다.

docker pull postgres:latest

이제 PostgreSQL 컨테이너를 실행합니다. 아래 명령어로 컨테이너를 실행하면서 데이터베이스 이름, 사용자, 비밀번호를 설정합니다.

docker run --name my_postgres -e POSTGRES_USER=myuser -e POSTGRES_PASSWORD=mypassword -e POSTGRES_DB=mydatabase -p 5432:5432 -d postgres
  • my_postgres: 컨테이너 이름
  • POSTGRES_USER: 데이터베이스 사용자 이름 (myuser).
  • POSTGRES_PASSWORD: 데이터베이스 비밀번호 (mypassword).
  • POSTGRES_DB: 생성할 기본 데이터베이스 이름 (mydatabase).
  • p 5432:5432: 호스트와 컨테이너 간의 포트 매핑 (호스트의 5432 포트를 컨테이너의 5432 포트와 연결).
  • d: 백그라운드에서 컨테이너를 실행.

이 명령어를 실행하면 PostgreSQL이 백그라운드에서 실행되고, 5432 포트에서 연결을 대기하게 됩니다.

저는 아래와 같이 입력하였습니다!

docker run --name ktor-db -e POSTGRES_USER=mic050r -e POSTGRES_PASSWORD=123456 -e POSTGRES_DB=test -p 5432:5432 -d postgres

1.2. 컨테이너 확인

다음 명령어로 컨테이너가 제대로 실행 중인지 확인할 수 있습니다.

docker ps

컨테이너가 정상적으로 실행 중이라면, 5432 포트에서 PostgreSQL이 실행되고 있는 것을 확인할 수 있습니다.

2. Ktor와 PostgreSQL 연결

PostgreSQL이 Docker에서 실행 중이라면, 이제 Ktor 프로젝트에서 이 데이터베이스에 연결하는 방법을 설정해야 합니다.

2.1. JDBC URL 설정

Application.kt 또는 환경 변수 파일에서 PostgreSQL에 연결하기 위한 JDBC URL을 설정합니다. PostgreSQL Docker 컨테이너가 로컬에서 실행 중이므로, localhost5432 포트를 사용합니다.

val hikariConfig = HikariConfig().apply {
    jdbcUrl = "jdbc:postgresql://localhost:5432/mydatabase"
    driverClassName = "org.postgresql.Driver"
    username = "myuser"
    password = "mypassword"
    maximumPoolSize = 10
}

val dataSource = HikariDataSource(hikariConfig)
Database.connect(dataSource)
  • jdbcUrl: "jdbc:postgresql://localhost:5432/mydatabase"로 설정.localhost는 Docker 컨테이너가 호스트의 네트워크에서 접근 가능하기 때문에 사용
  • username: myuser (컨테이너 실행 시 설정한 사용자 이름)
  • password: mypassword (컨테이너 실행 시 설정한 비밀번호)

2.2. 의존성 추가

Ktor 프로젝트에서 PostgreSQL과 HikariCP를 사용할 수 있도록 build.gradle.kts 파일에 의존성을 추가해야 합니다.

dependencies {
    // PostgreSQL JDBC 드라이버
    implementation("org.postgresql:postgresql:42.6.0")

    // Exposed ORM 라이브러리
    implementation("org.jetbrains.exposed:exposed-core:0.41.1")
    implementation("org.jetbrains.exposed:exposed-dao:0.41.1")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1")

    // HikariCP (커넥션 풀)
    implementation("com.zaxxer:HikariCP:5.0.1")
}

3. 데이터베이스 연결

package example.com

import example.com.plugins.*
import io.ktor.server.application.*
import io.ktor.server.netty.*
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.jetbrains.exposed.sql.Database

fun main(args: Array<String>) {
    EngineMain.main(args)
}

fun Application.module() {
    // 데이터베이스 설정을 여기서 초기화
    configureDatabase()

    // 다른 설정들
    configureSerialization()
    configureHTTP()
    configureSecurity()
    configureRouting()
}

fun Application.configureDatabase() {
    val hikariConfig = HikariConfig().apply {
        jdbcUrl = "jdbc:postgresql://localhost:5432/test"
        driverClassName = "org.postgresql.Driver"
        username = "mic050r"
        password = "123456"
        maximumPoolSize = 10
    }

    try {
        val dataSource = HikariDataSource(hikariConfig)
        Database.connect(dataSource)
        // 연결 성공 시 로그 출력
        environment.log.info("Database connected successfully!")
    } catch (e: Exception) {
        // 연결 실패 시 오류 로그 출력
        environment.log.error("Database connection failed: ${e.message}")
    }
}

4. Ktor 실행 및 확인

로그를 보니 잘 실행되는 것을 확인했습니다!

5. 전체 코드

5-1. src/main/kotlin/example/com/Application.kt

package example.com

import example.com.plugins.*
import io.ktor.server.application.*
import io.ktor.server.netty.*
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import org.jetbrains.exposed.sql.Database

fun main(args: Array<String>) {
    EngineMain.main(args)
}

fun Application.module() {
    // 데이터베이스 설정을 여기서 초기화
    configureDatabase()

    // 다른 설정들
    configureSerialization()
    configureHTTP()
    configureSecurity()
    configureRouting()
}

fun Application.configureDatabase() {
    val hikariConfig = HikariConfig().apply {
        jdbcUrl = "jdbc:postgresql://localhost:5432/test"
        driverClassName = "org.postgresql.Driver"
        username = "mic050r"
        password = "123456"
        maximumPoolSize = 10
    }

    try {
        val dataSource = HikariDataSource(hikariConfig)
        Database.connect(dataSource)
        // 연결 성공 시 로그 출력
        environment.log.info("Database connected successfully!")
    } catch (e: Exception) {
        // 연결 실패 시 오류 로그 출력
        environment.log.error("Database connection failed: ${e.message}")
    }
}

5-2. build.gradle.kts


val kotlin_version: String by project
val logback_version: String by project
val exposed_version: String by project
val h2_version: String by project

plugins {
    kotlin("jvm") version "2.0.10"
    id("io.ktor.plugin") version "2.3.12"
    id("org.jetbrains.kotlin.plugin.serialization") version "2.0.10"
}

group = "example.com"
version = "0.0.1"

application {
    mainClass.set("io.ktor.server.netty.EngineMain")

    val isDevelopment: Boolean = project.ext.has("development")
    applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.jetbrains.exposed:exposed-core:0.41.1")
    implementation("org.jetbrains.exposed:exposed-dao:0.41.1")
    implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1")

    implementation("io.ktor:ktor-server-core-jvm")
    implementation("io.ktor:ktor-serialization-kotlinx-json-jvm")
    implementation("io.ktor:ktor-server-content-negotiation-jvm")

    // Exposed ORM 라이브러리
    implementation("org.jetbrains.exposed:exposed-core:$exposed_version")
    implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version")

    // PostgreSQL JDBC 드라이버
    implementation("org.postgresql:postgresql:42.6.0")

    // HikariCP (커넥션 풀)
    implementation("com.zaxxer:HikariCP:5.0.1")

    implementation("com.h2database:h2:$h2_version")
    implementation("io.ktor:ktor-server-openapi")
    implementation("io.ktor:ktor-server-auth-jvm")
    implementation("io.ktor:ktor-server-netty-jvm")
    implementation("ch.qos.logback:logback-classic:$logback_version")
    implementation("io.ktor:ktor-server-config-yaml")
    testImplementation("io.ktor:ktor-server-test-host-jvm")
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
}

깃허브 코드

profile
프로젝트를 통해 배운 개념이나 겪은 문제점들을 정리하고, 회고록을 작성하며 성장해나가는 곳입니다 😊

0개의 댓글

관련 채용 정보