未使用docker-compose将SBT项目安装到Docker容器

问题描述 投票:0回答:1

[当我运行docker-compose up --build时,数据库容器运行良好,但是应用容器与]一起存在>

[error] java.lang.RuntimeException: No main class detected.
[error]     at scala.sys.package$.error(package.scala:30)
[error] stack trace is suppressed; run 'last Compile / bgRun' for the full output
[error] (Compile / bgRun) No main class detected.
[error] Total time: 3 s, completed Apr 30, 2020 10:07:31 AM
ERROR: Service 'app' failed to build: The command 'sbt run' returned a non-zero code: 1

我的Dockerfile:

FROM        hseeberger/scala-sbt:8u222_1.3.5_2.13.1
MAINTAINER  <HIDDEN>
EXPOSE      8080 8000

WORKDIR     /www/app

VOLUME /www/app

RUN ["sbt", "run"]

我的docker-compose.yml:

version: "3.3"
services:
  db:
    image: postgres:latest
    ports:
      - "5432:5432"
  app:
    build: .
    ports:
     - "8080:8080"
     - "8000:8000"
    volumes:
     - ..:/www/app

我的Scala项目结构:

Project structure

Main.scala仅包含一个非常简单的Hello World,如您所见:

object Main extends App {
  println("Hello from main scala object")
}

如果我使用RUN ["sbt"]中的Dockerfile运行容器,则容器保持运行状态。我通过docker exec -it adcc9897d1fc bash连接,可以看到/www/app文件夹为空(除了sbt创建的文件夹之外)。知道为什么它为空并且不包含项目吗?

[当我运行docker-compose up --build时,数据库容器运行良好,但是应用容器存在[错误] java.lang.RuntimeException:未检测到主类。 scala.sys.package $ .error(...]处的[错误]

首先考虑并处理Dockerfile,然后再考虑docker-compose.yml文件中的大多数其他选项。特别是,映像构建永远不会从Docker Compose设置中看到volumes:(它也看不到environment:变量或任何与网络相关的设置,包括default网络)。
这意味着
在构建时(因为它是RUN指令),因此您试图在空的匿名卷上运行sbt run。这会产生“没有主类”错误。

对于基于JVM的语言,典型的设置是在主机上编译应用程序,然后将(便携式)COPY文件.jar编译到映像中。 sbt-native-packager插件实际上可以do all of this for you;如果您希望手动执行此操作,则sbt-assembly plugin可以产生一个包含所有应用程序依赖项的“胖” sbt-assembly。然后,您将获得典型的最小JVM Dockerfile

.jar如果要在Dockerfile中编译应用程序,则需要FROM openjdk:8 COPY target/scala-2.13/my-app-*.jar /my-app.jar CMD ["java", "-jar", "/my-app.jar"] 该应用程序,并设置COPY以在容器启动时(而不是在构建期间)运行该应用程序。

CMD

((您也可以使用FROM hseeberger/scala-sbt:8u222_1.3.5_2.13.1
WORKDIR /www/app

# Copy the application source in.
COPY ./ ./

# Build it.
RUN sbt compile

# Set the command to run and other metadata when the container starts.
EXPOSE 8000 8080
CMD sbt run
组合这两个Dockerfile:首先multi-stage build源树,然后COPY它,然后在第二阶段sbt compile仅将jar文件转换为仅JRE的映像。 )

由于COPY --from=build指令,您需要将构建上下文设置为源树的根。 (将COPYDockerfile移动到docker-compose.yml文件旁边的存储库根目录可能会更容易。)

build.sbt

原则上,您可以像在问题中一样将应用程序代码绑定装入其中,然后version: "3.3" services: app: build: context: .. dockerfile: docker/Dockerfile ports: - "8080:8080" - "8000:8000" # No need for volumes:, source code is already in the image 命令将重新编译它。您在Dockerfile中不需要sbt run指令。您可能会发现在宿主JDK / sbt环境中进行日常开发会更容易。

scala docker docker-compose sbt dockerfile
1个回答
1
投票
在构建时(因为它是RUN指令),因此您试图在空的匿名卷上运行sbt run。这会产生“没有主类”错误。
© www.soinside.com 2019 - 2024. All rights reserved.