RUN
指令),因此您试图在空的匿名卷上运行sbt run
。这会产生“没有主类”错误。[当我运行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项目结构:
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(...]处的[错误]
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
指令,您需要将构建上下文设置为源树的根。 (将COPY
和Dockerfile
移动到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环境中进行日常开发会更容易。
RUN
指令),因此您试图在空的匿名卷上运行sbt run
。这会产生“没有主类”错误。