调试使用 SBT Native Packager 构建的 Docker 应用程序

Debug Docker application built with SBT Native Packager

我正在尝试调试我的 Scala.js 应用程序的服务器。我使用 SBT Docker plugin to generate a Dockerfile and the SBT Native Packager 构建应用程序。

我想使用 IntelliJ 的调试器,所以我将其配置为远程调试。请参阅下面的屏幕截图:

我必须将其添加到我的 build.sbtjvmSettings 部分:

javaOptions in Universal ++= Seq("-jvm-debug 5005"),

此外,在 docker-compose.yml 中,必须打开调试端口:

services:
  myApp:    
    image: registry.gitlab.com/bullbytes/myApp:latest
    ports:
      # Debugging port
      - "5005:5005"

对于某些上下文,这是我的 build.sbt:

的简化但完整的版本
scalaVersion in ThisBuild := "2.11.8"
// Whether we are in production or development mode
val isDevMode = true

lazy val root = project.in(file(".")).
  aggregate(client, server).
  settings(
    name := "My app root"
  )

// We can run this project by calling appJS/run and appJVM/run. Enter `projects` in SBT to see the name of all projects
lazy val app = crossProject.in(file("./app")).
  settings(
    name := "my application"
  ).
  jvmSettings(
    libraryDependencies ++= /* my server-side dependencies*/,
    // Enable debugging
    javaOptions in Universal ++= Seq(
      "-jvm-debug 5005"
    ),
    imageNames in docker := {
      Seq(
        ImageName(
          repository = "registry.gitlab.com/bullbytes/myApp",
          tag = Some("my tag")
        )
      )
    },
    dockerfile in docker := {
      val appDir = stage.value
      val targetDir = "/app"
      new Dockerfile {
        from("java:8-jre")
        entryPoint(s"$targetDir/bin/${executableScriptName.value}")
        copy(appDir, targetDir)
        expose(8080)
      }
    }

    /**
      * We enable JavaAppPackaging to create a jar. Also, this gives us access to the variables stage and executableScriptName.
      * Issuing "appJVM/docker" in SBT creates a Docker image from that jar.
      */
  ).enablePlugins(JavaAppPackaging, sbtdocker.DockerPlugin).
  jsSettings(

    libraryDependencies ++= /* my client-side Scala.js dependencies*/,
    jsDependencies ++= /* my client-side JavaScript dependencies*/,

    // Include the JavaScript dependencies
    skip in packageJSDependencies := false,

    // Use the faster Node.js instead of Rhino. Get Node.js from here: https://nodejs.org
    //scalaJSUseRhino in Global := false

    // Regardless of whether we optimize the created JavaScript fast or fully, produce a .js file with the same name.
    // This way, we don't have to adapt the name of the script to load at the client when we switch optimize modes
    artifactPath in Compile in fastOptJS := (crossTarget in fastOptJS).value / ((moduleName in fastOptJS).value + ".js"),
    artifactPath in Compile in fullOptJS := (crossTarget in fullOptJS).value / ((moduleName in fullOptJS).value + ".js"),

    persistLauncher in Compile := true,
    persistLauncher in Test := false
  )

// We need to define the subprojects. Note that the names of these vals do not affect how you run the subprojects:
// It will be `<nameOfCrossProject>JS/run` and `<nameOfCrossProject>JVM/run`, irrespective of how these vals are named
lazy val client = app.js.settings()

/**
  * Adds the compiled JavaScript to the server's resources since the server sends the JavaScript to the client
  *
  * @return a sequence of files that consists of our generated JavaScript file. Wrapped in a setting task for SBT
  */
def addJavaScriptToServerResources() = {
  if (isDevMode) {
    (resources in Compile) += (fastOptJS in(client, Compile)).value.data
  } else {
    (resources in Compile) += (fullOptJS in(client, Compile)).value.data
  }
}
def addJSDependenciesToServerResources() = {
  (resources in Compile) += (packageMinifiedJSDependencies in(client, Compile)).value
}
lazy val server = app.jvm.settings(
  addJavaScriptToServerResources(),
  addJSDependenciesToServerResources(),

  /*
    Setting 'persistLauncher' to true generates a small JavaScript launcher that calls the main method in the client.
    The server sends the launcher script to the client.
    See also: https://www.scala-js.org/tutorial/basic/#automatically-creating-a-launcher
  */
  (resources in Compile) += (packageScalaJSLauncher in(client, Compile)).value.data
)

以下是 SBT Native Packager 生成的启动脚本的更多选项:link