feat: Update Dockerfile for multi-platform support and add nginx configuration
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# === Stage 1: Build the Play application ===
|
# === Stage 1: Build the Play application ===
|
||||||
FROM sbtscala/scala-sbt:eclipse-temurin-alpine-22_36_1.10.3_3.5.1 AS builder
|
FROM --platform=$BUILDPLATFORM sbtscala/scala-sbt:eclipse-temurin-alpine-22_36_1.10.3_3.5.1 AS builder
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ COPY . .
|
|||||||
RUN sbt -Dscoverage.skip=true clean stage
|
RUN sbt -Dscoverage.skip=true clean stage
|
||||||
|
|
||||||
# === Stage 2: Runtime image ===
|
# === Stage 2: Runtime image ===
|
||||||
FROM eclipse-temurin:21-jre-alpine
|
FROM --platform=$TARGETPLATFORM eclipse-temurin:22-jre-alpine
|
||||||
|
|
||||||
# Install Argon2 CLI and libraries
|
# Install Argon2 CLI and libraries
|
||||||
RUN apk add --no-cache bash argon2 argon2-libs
|
RUN apk add --no-cache bash argon2 argon2-libs
|
||||||
|
|||||||
@@ -35,12 +35,16 @@ lazy val knockoutwhistweb = project.in(file("knockoutwhistweb"))
|
|||||||
.enablePlugins(PlayScala)
|
.enablePlugins(PlayScala)
|
||||||
.dependsOn(knockoutwhist % "compile->compile;test->test")
|
.dependsOn(knockoutwhist % "compile->compile;test->test")
|
||||||
.settings(
|
.settings(
|
||||||
|
|
||||||
|
resolvers += "GitHub Packages" at "https://maven.pkg.github.com/16Janis12/KnockOutWhist-Web",
|
||||||
|
|
||||||
commonSettings,
|
commonSettings,
|
||||||
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.2" % Test,
|
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.2" % Test,
|
||||||
libraryDependencies += "de.mkammerer" % "argon2-jvm" % "2.12",
|
libraryDependencies += "de.mkammerer" % "argon2-jvm" % "2.12",
|
||||||
libraryDependencies += "com.auth0" % "java-jwt" % "4.5.0",
|
libraryDependencies += "com.auth0" % "java-jwt" % "4.5.0",
|
||||||
libraryDependencies += "com.github.ben-manes.caffeine" % "caffeine" % "3.2.3",
|
libraryDependencies += "com.github.ben-manes.caffeine" % "caffeine" % "3.2.3",
|
||||||
libraryDependencies += "tools.jackson.module" %% "jackson-module-scala" % "3.0.2",
|
libraryDependencies += "tools.jackson.module" %% "jackson-module-scala" % "3.0.2",
|
||||||
|
libraryDependencies += "de.janis" % "knockoutwhist-data" % "1.0-SNAPSHOT",
|
||||||
JsEngineKeys.engineType := JsEngineKeys.EngineType.Node
|
JsEngineKeys.engineType := JsEngineKeys.EngineType.Node
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Submodule knockoutwhistfrontend updated: db5c70d02a...e972f1c432
45
knockoutwhistweb/app/logic/Gateway.scala
Normal file
45
knockoutwhistweb/app/logic/Gateway.scala
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package logic
|
||||||
|
|
||||||
|
import de.knockoutwhist.data.Pod
|
||||||
|
import de.knockoutwhist.data.redis.RedisManager
|
||||||
|
import org.apache.pekko.actor.ActorSystem
|
||||||
|
import org.redisson.config.Config
|
||||||
|
import play.api.inject.ApplicationLifecycle
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
import javax.inject.*
|
||||||
|
import scala.concurrent.ExecutionContext
|
||||||
|
import scala.jdk.CollectionConverters.*
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class Gateway @Inject()(
|
||||||
|
lifecycle: ApplicationLifecycle,
|
||||||
|
actorSystem: ActorSystem
|
||||||
|
)(implicit ec: ExecutionContext) {
|
||||||
|
|
||||||
|
val redis: RedisManager = {
|
||||||
|
val config: Config = Config()
|
||||||
|
config.useSingleServer.setAddress("valkey://" + sys.env.getOrElse("VALKEY_HOST", "localhost") + ":" + sys.env.getOrElse("VALKEY_PORT", "6379"))
|
||||||
|
RedisManager(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
redis.continuousSyncPod(() => {
|
||||||
|
createPod()
|
||||||
|
})
|
||||||
|
|
||||||
|
def syncPod(): Unit = {
|
||||||
|
redis.syncPod(createPod())
|
||||||
|
}
|
||||||
|
|
||||||
|
private def createPod(): Pod = {
|
||||||
|
Pod(
|
||||||
|
UUID.randomUUID().toString,
|
||||||
|
PodManager.podName,
|
||||||
|
PodManager.podIp,
|
||||||
|
9000,
|
||||||
|
PodManager.getAllGameIds().asJava,
|
||||||
|
PodManager.allBoundUsers().asJava
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@ object PodManager {
|
|||||||
private val userSession: mutable.Map[User, String] = mutable.Map()
|
private val userSession: mutable.Map[User, String] = mutable.Map()
|
||||||
private val injector: Injector = Guice.createInjector(KnockOutWebConfigurationModule())
|
private val injector: Injector = Guice.createInjector(KnockOutWebConfigurationModule())
|
||||||
|
|
||||||
|
private[logic] var redis: Option[Gateway] = None
|
||||||
|
|
||||||
def createGame(
|
def createGame(
|
||||||
host: User,
|
host: User,
|
||||||
name: String,
|
name: String,
|
||||||
@@ -35,7 +37,8 @@ object PodManager {
|
|||||||
host = host
|
host = host
|
||||||
)
|
)
|
||||||
sessions += (gameLobby.id -> gameLobby)
|
sessions += (gameLobby.id -> gameLobby)
|
||||||
userSession += (host -> gameLobby.id)
|
registerUserToGame(host, gameLobby.id)
|
||||||
|
redis.foreach(gateway => gateway.syncPod())
|
||||||
gameLobby
|
gameLobby
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +49,7 @@ object PodManager {
|
|||||||
def registerUserToGame(user: User, gameId: String): Boolean = {
|
def registerUserToGame(user: User, gameId: String): Boolean = {
|
||||||
if (sessions.contains(gameId)) {
|
if (sessions.contains(gameId)) {
|
||||||
userSession += (user -> gameId)
|
userSession += (user -> gameId)
|
||||||
|
redis.foreach(gateway => gateway.syncPod())
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -54,6 +58,7 @@ object PodManager {
|
|||||||
|
|
||||||
def unregisterUserFromGame(user: User): Unit = {
|
def unregisterUserFromGame(user: User): Unit = {
|
||||||
userSession.remove(user)
|
userSession.remove(user)
|
||||||
|
redis.foreach(gateway => gateway.redis.invalidateUser(user.id.toString))
|
||||||
}
|
}
|
||||||
|
|
||||||
def identifyGameOfUser(user: User): Option[GameLobby] = {
|
def identifyGameOfUser(user: User): Option[GameLobby] = {
|
||||||
@@ -65,9 +70,12 @@ object PodManager {
|
|||||||
|
|
||||||
private[logic] def removeGame(gameId: String): Unit = {
|
private[logic] def removeGame(gameId: String): Unit = {
|
||||||
sessions.remove(gameId)
|
sessions.remove(gameId)
|
||||||
|
redis.foreach(gateway => gateway.redis.invalidateGame(gameId))
|
||||||
// Also remove all user sessions associated with this game
|
// Also remove all user sessions associated with this game
|
||||||
userSession.filterInPlace((_, v) => v != gameId)
|
userSession.filterInPlace((_, v) => v != gameId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private[logic] def getAllGameIds(): List[String] = sessions.keys.toList
|
||||||
|
private[logic] def allBoundUsers(): List[String] = userSession.keys.map(_.id.toString).toList
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ class GameLobby private(
|
|||||||
}
|
}
|
||||||
if (sessionOpt.get.host) {
|
if (sessionOpt.get.host) {
|
||||||
logic.invoke(SessionClosed())
|
logic.invoke(SessionClosed())
|
||||||
|
for (session <- users.values) {
|
||||||
|
PodManager.unregisterUserFromGame(session.user)
|
||||||
|
}
|
||||||
users.clear()
|
users.clear()
|
||||||
PodManager.removeGame(id)
|
PodManager.removeGame(id)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ auth {
|
|||||||
play.filters.enabled += "play.filters.cors.CORSFilter"
|
play.filters.enabled += "play.filters.cors.CORSFilter"
|
||||||
|
|
||||||
play.filters.cors {
|
play.filters.cors {
|
||||||
allowedOrigins = ["http://localhost:5173", "http://localhost:3000"]
|
allowedOrigins = ["http://localhost:5173", "http://localhost:3000", "http://localhost:8081"]
|
||||||
allowedCredentials = true
|
allowedCredentials = true
|
||||||
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
||||||
allowedHttpHeaders = ["Accept", "Content-Type", "Origin", "X-Requested-With"]
|
allowedHttpHeaders = ["Accept", "Content-Type", "Origin", "X-Requested-With"]
|
||||||
|
|||||||
Reference in New Issue
Block a user