Google Cloud Run Scala 3 + Akka Abruptly terminate

54 Views Asked by At

I set up a Scala project to run on Cloud Run, but immediately after it starts, I receive Success logs, and then it shuts down abruptly.

import akka.actor.typed.ActorSystem
import akka.actor.typed.scaladsl.Behaviors
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.*
import akka.http.scaladsl.server.Directives.*
import org.slf4j.LoggerFactory

import scala.concurrent.duration.*
import scala.concurrent.{ExecutionContextExecutor, Future}
import scala.util.{Failure, Success}

object Main extends App {
  implicit val system =
    ActorSystem(Behaviors.empty, "my-system")
  implicit val executionContext: ExecutionContextExecutor =
    system.executionContext

  val logger = LoggerFactory.getLogger(this.getClass)

  val route = path("fetch-api") {
    get {
      onComplete(fetchApiData()) {
        case Success(value) =>
          logger.info(s"API Response: $value")
          complete(value)
        case Failure(ex) => complete(s"An error occurred: ${ex.getMessage}")
      }
    }
  }

  val port = sys.env.getOrElse("PORT", "8080").toInt
  val bindingFuture = Http().newServerAt("0.0.0.0", port).bind(route)

  bindingFuture.onComplete {
    case Success(binding) =>
      logger.info(
        s"Server online at http://${binding.localAddress.getHostString}:${binding.localAddress.getPort}/"
      )
    case Failure(exception) =>
      logger.error(s"Failed to bind to $port: ${exception.getMessage}")
      system.terminate()
  }

  def fetchApiData(): Future[String] = {
    val request = HttpRequest(uri = "https://api.publicapis.org/entries")
    logger.info(
      "Starting method fetchApiData on URI: https://api.publicapis.org/entries"
    )

    Http()
      .singleRequest(request)
      .flatMap { response =>
        logger.info(s"Status da Resposta HTTP: ${response.status}")
        response.entity.toStrict(60.seconds).map { entity =>
          entity.data.utf8String
        }
      }
      .recover { case ex =>
        s"An error occurred: ${ex.getMessage}"
      }
  }
}

Dockerfile

FROM openjdk:11-slim

RUN apt-get update && apt-get install -y curl && curl -sL "https://github.com/sbt/sbt/releases/download/v1.9.8/sbt-1.9.8.tgz" | tar -xz -C /usr/local && ln -s /usr/local/sbt/bin/sbt /usr/local/bin/sbt && apt-get clean

WORKDIR /app

COPY . /app

RUN sbt compile

RUN apt-get update && apt-get install -y curl

EXPOSE 8080

ENV PORT 8080

CMD ["sbt", "run"]

build.sbt

import sbt.Keys.libraryDependencies

ThisBuild / version := "scala-http"

ThisBuild / scalaVersion := "3.3.1"

mainClass := Some("Main")

lazy val root = (project in file("."))
  .settings(
    name := "Test",
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http" % "10.5.0",
      "com.typesafe.akka" %% "akka-actor-typed" % "2.8.5",
      "com.typesafe.akka" %% "akka-stream" % "2.8.5",
      "ch.qos.logback" % "logback-classic" % "1.4.14"
    )
  )

Logs:

\[info\] welcome to sbt 1.9.8 (Oracle Corporation Java 11.0.16)
\[info\] loading settings for project app-build from plugins.sbt ...
\[info\] loading project definition from /app/project
\[info\] loading settings for project root from build.sbt ...
\[info\] set current project to Test (in build file:/app/)
\[warn\] there's a key that's not used by any other settings/tasks:
\[warn\] \* root / mainClass
\[warn\]   +- /app/build.sbt:12
\[warn\] note: a setting might still be used by a command; to exclude a key from this `lintUnused` check
\[warn\] either append it to `Global / excludeLintKeys` or call .withRank(KeyRanks.Invisible) on the key
\[info\] running Main
\[my-system-akka.actor.default-dispatcher-3\] INFO akka.event.slf4j.Slf4jLogger -- Slf4jLogger started
Default STARTUP TCP probe succeeded after 1 attempt for container "scala3-test-1" on port 8080.
\[success\] Total time: 11 s, completed Feb 1, 2024, 6:46:42 PM
Server online at http://0.0.0.0:8080/

I tried to use the sbt docker:publishLocal with the plugin "com.github.sbt" % "sbt-native-packager" % "1.9.8" and some parameters on build.sbt dockerBaseImage := "openjdk:11" dockerExposedPorts := Seq(8080), but with this plugin the error is Revision is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable.

Any help would be great on how to create a cloud run with Scala.

0

There are 0 best solutions below