diff --git a/.run/Compose up.run.xml b/.run/Compose up.run.xml new file mode 100644 index 0000000..69723f1 --- /dev/null +++ b/.run/Compose up.run.xml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/.run/composeUp.run.xml b/.run/composeUp.run.xml deleted file mode 100644 index 9548ecb..0000000 --- a/.run/composeUp.run.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - true - true - false - false - - - \ No newline at end of file diff --git a/README.md b/README.md index 8f525ca..d360b12 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ Event demo ========== +To run the stack: + +```shell +docker compose -f docker\docker-compose.yaml -p event-demo up -d +``` + Admin service URL: - [Traefik](http://pgadmin.traefik.me/) - [Redis](http://pgadmin.traefik.me/) - - [pgAdmin](http://pgadmin.traefik.me/) \ No newline at end of file + - [pgAdmin](http://pgadmin.traefik.me/) + - [API](http://api.traefik.me/) \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 72bbf39..b6df0fa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,15 +9,15 @@ val kotlin_logging_version: String by project val kotest_version: String by project plugins { + application kotlin("jvm") version "2.1.10" - id("io.ktor.plugin") version "2.3.13" + id("io.ktor.plugin") version "3.1.1" id("org.jetbrains.kotlin.plugin.serialization") version "2.1.10" id("org.jlleitschuh.gradle.ktlint") version "12.2.0" id("com.avast.gradle.docker-compose") version "0.17.12" } group = "io.github.flecomte" -version = "0.0.1" application { mainClass.set("eventDemo.ApplicationKt") @@ -36,7 +36,7 @@ repositories { java { toolchain { - languageVersion = JavaLanguageVersion.of(19) + languageVersion = JavaLanguageVersion.of(21) } } diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..008291d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,25 @@ +# Stage 1: Cache Gradle dependencies +FROM gradle:latest AS cache +RUN mkdir -p /home/gradle/cache_home +ENV GRADLE_USER_HOME=/home/gradle/cache_home +COPY build.gradle.* gradle.properties /home/gradle/app/ +COPY .editorconfig /home/gradle/app/ +COPY gradle /home/gradle/app/gradle +WORKDIR /home/gradle/app +RUN gradle clean build -i -x test -x ktlintCheck -x ktlintKotlinScriptCheck + +# Stage 2: Build Application +FROM gradle:latest AS build +COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +# Build the fat JAR, Gradle also supports shadow +# and boot JAR by default. +RUN gradle buildFatJar --no-daemon + +# Stage 3: Create the Runtime Image +FROM amazoncorretto:21 AS runtime +EXPOSE 8080 +RUN mkdir /app +COPY --from=build /home/gradle/src/build/libs/*.jar /app/event-demo-all.jar +ENTRYPOINT ["java","-jar","/app/event-demo-all.jar"] \ No newline at end of file diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index e8b383c..cfbf42b 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -1,3 +1,4 @@ +name: event-demo services: traefik: image: traefik:3.3.4 @@ -42,6 +43,7 @@ services: volumes: - ../migrations/events:/flyway/sql - ./flyway.conf:/flyway/conf/flyway.conf + restart: no postgresql: image: postgres:17.4 @@ -75,6 +77,21 @@ services: - "traefik.http.routers.pgadmin.rule=Host(`pgadmin.traefik.me`)" - "traefik.http.services.pgadmin.loadbalancer.server.port=80" + app: + build: + context: ../ + dockerfile: docker/Dockerfile + ports: + - "8080:8080" + depends_on: + flyway: + condition: service_completed_successfully + postgresql: + condition: service_healthy + labels: + - "traefik.http.routers.app.rule=Host(`api.traefik.me`)" + - "traefik.http.services.app.loadbalancer.server.port=8080" + secrets: pgadmin_password: file: pgadmin.secret diff --git a/src/main/kotlin/eventDemo/Application.kt b/src/main/kotlin/eventDemo/Application.kt index 04093ff..1cdfb10 100644 --- a/src/main/kotlin/eventDemo/Application.kt +++ b/src/main/kotlin/eventDemo/Application.kt @@ -1,16 +1,6 @@ package eventDemo -import eventDemo.configuration.configure -import io.ktor.server.application.Application -import io.ktor.server.engine.embeddedServer -import io.ktor.server.netty.Netty +import io.ktor.server.netty.EngineMain -fun main() { - embeddedServer( - factory = Netty, - port = 8080, - host = "0.0.0.0", - module = Application::configure, - watchPaths = listOf("classes"), - ).start(wait = true) -} +fun main(args: Array): Unit = + EngineMain.main(args) diff --git a/src/main/kotlin/eventDemo/configuration/ktor/ConfigureWebSockets.kt b/src/main/kotlin/eventDemo/configuration/ktor/ConfigureWebSockets.kt index 9439eca..e97f11a 100644 --- a/src/main/kotlin/eventDemo/configuration/ktor/ConfigureWebSockets.kt +++ b/src/main/kotlin/eventDemo/configuration/ktor/ConfigureWebSockets.kt @@ -5,12 +5,12 @@ import io.ktor.server.application.install import io.ktor.server.websocket.WebSockets import io.ktor.server.websocket.pingPeriod import io.ktor.server.websocket.timeout -import java.time.Duration +import kotlin.time.Duration.Companion.seconds fun Application.configureWebSockets() { install(WebSockets) { - pingPeriod = Duration.ofSeconds(15) - timeout = Duration.ofSeconds(15) + pingPeriod = 15.seconds + timeout = 15.seconds maxFrameSize = Long.MAX_VALUE masking = false } diff --git a/src/main/kotlin/eventDemo/configuration/route/DeclareHttpRoutes.kt b/src/main/kotlin/eventDemo/configuration/route/DeclareHttpRoutes.kt index 1fe1cf1..6cd1f14 100644 --- a/src/main/kotlin/eventDemo/configuration/route/DeclareHttpRoutes.kt +++ b/src/main/kotlin/eventDemo/configuration/route/DeclareHttpRoutes.kt @@ -8,7 +8,7 @@ import org.koin.ktor.ext.get fun Application.declareHttpGameRoute() { routing { - readTheGameState(get()) - readGamesList(get()) + readTheGameState(this@declareHttpGameRoute.get()) + readGamesList(this@declareHttpGameRoute.get()) } } diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 18e0be2..3d918c1 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,3 +1,13 @@ +ktor { + deployment { + port = 8080 + host = 0.0.0.0 + } + application { + modules = [ eventDemo.configuration.ConfigureKt.configure ] + } +} + jwt { secret = "secret" secret = ${?JWT_SECRET}