使用 docker 的多阶段构建 Scala 项目
Building Scala project with docker's Multi-Stage
我正在尝试构建一个具有 docker 多阶段能力的 Scala 项目。
首先,这是我的docker文件:
FROM maven:3.6.0-jdk-11-slim AS maven
RUN apt-get update
WORKDIR /build
COPY pom.xml .
RUN mvn -B de.qaware.maven:go-offline-maven-plugin:resolve-dependencies
COPY src src
RUN mvn -B -o install spring-boot:repackage
FROM openjdk:11.0.6
WORKDIR /opt/app
COPY --from=maven /build/target/app.jar app.jar
CMD ["java", "-jar", "/opt/app/app.jar"]
EXPOSE 8080
我注意到在完成 resolve-dependencies 部分后,maven 仍在尝试在安装阶段下载依赖项。我得到的错误与 scala-maven-plugin 有关,它寻找在解析阶段没有获取的不存在的依赖项。错误如下所示:
Failed to execute goal
net.alchim31.maven:scala-maven-plugin:3.4.0:compile (default) on
project app: wrap:
org.apache.maven.artifact.resolver.ArtifactNotFoundException: Cannot
access ... in
offline mode and the artifact
org.scala-lang:scala-compiler:jar:2.11.12 has not been downloaded from
it before.
即使添加这个依赖项也是不够的,因为它在另一个依赖项上失败了。
POM 中的插件如下所示:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<goals>
<!-- Need to specify this explicitly, otherwise plugin won't be called when doing e.g. mvn compile -->
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<!-- work-around for https://issues.scala-lang.org/browse/SI-8358 -->
<arg>-nobootcp</arg>
<arg>-Yresolve-term-conflict:package</arg>
</args>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
似乎插件并没有就此停止并重新下载所有内容。
谢谢大家..
就像对您的问题发表评论一样,最好使用 sbt
作为 Scala
的第一个公民构建工具。特别是我建议使用 sbt-native-packager in conjunction with the plugins JavaAppPackaging
and DockerPlugin
to create the docker image without a Dockerfile
. There are some tutorials to create it on the web. Basically, you will need something like these lines on your build.sbt
file (example from my project).
enablePlugins(JavaAppPackaging, JavaServerAppPackaging, DockerPlugin, AshScriptPlugin)
// ####### Dockerfile settings #######
import NativePackagerHelper._
packageName in Docker := packageName.value
version in Docker := version.value
dockerExposedPorts := List(8001, 2551)
dockerLabels := Map("user" -> "you.email@gmail.com")
dockerBaseImage := "openjdk:jre-alpine"
dockerRepository := Some("docker.user.name")
defaultLinuxInstallLocation in Docker := "/usr/local"
daemonUser in Docker := "daemon"
mappings in Universal ++= directory( baseDirectory.value / "src" / "main" / "resources" )
// ####### Dockerfile settings #######
并在 project/plugins.sbt
文件中:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")
然后您在控制台上执行以下命令以在 target/docker/stage/Dockerfile
.
处创建 Dockerfile
sbt docker:stage
sbt docker:publishLocal
最后,为了解决这个问题,我将这个插件用于 'go-offline' 而不是 Maven 的:
<plugin>
<groupId>de.qaware.maven</groupId>
<artifactId>go-offline-maven-plugin</artifactId>
<version>1.2.8</version>
</plugin>
通过以下命令使用它:
mvn -B de.qaware.maven:go-offline-maven-plugin:resolve-dependencies
还在 scala-maven-plugin 中添加了禁用增量编译依赖项的配置:
<configuration>
<recompileMode>all</recompileMode>
</configuration>
所以完整的插件看起来像这样:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.4.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<recompileMode>all</recompileMode>
</configuration>
</plugin>
我正在尝试构建一个具有 docker 多阶段能力的 Scala 项目。
首先,这是我的docker文件:
FROM maven:3.6.0-jdk-11-slim AS maven
RUN apt-get update
WORKDIR /build
COPY pom.xml .
RUN mvn -B de.qaware.maven:go-offline-maven-plugin:resolve-dependencies
COPY src src
RUN mvn -B -o install spring-boot:repackage
FROM openjdk:11.0.6
WORKDIR /opt/app
COPY --from=maven /build/target/app.jar app.jar
CMD ["java", "-jar", "/opt/app/app.jar"]
EXPOSE 8080
我注意到在完成 resolve-dependencies 部分后,maven 仍在尝试在安装阶段下载依赖项。我得到的错误与 scala-maven-plugin 有关,它寻找在解析阶段没有获取的不存在的依赖项。错误如下所示:
Failed to execute goal net.alchim31.maven:scala-maven-plugin:3.4.0:compile (default) on project app: wrap: org.apache.maven.artifact.resolver.ArtifactNotFoundException: Cannot access ... in offline mode and the artifact org.scala-lang:scala-compiler:jar:2.11.12 has not been downloaded from it before.
即使添加这个依赖项也是不够的,因为它在另一个依赖项上失败了。
POM 中的插件如下所示:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.4.0</version>
<executions>
<execution>
<goals>
<!-- Need to specify this explicitly, otherwise plugin won't be called when doing e.g. mvn compile -->
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<!-- work-around for https://issues.scala-lang.org/browse/SI-8358 -->
<arg>-nobootcp</arg>
<arg>-Yresolve-term-conflict:package</arg>
</args>
<scalaVersion>${scala.version}</scalaVersion>
</configuration>
</plugin>
似乎插件并没有就此停止并重新下载所有内容。 谢谢大家..
就像对您的问题发表评论一样,最好使用 sbt
作为 Scala
的第一个公民构建工具。特别是我建议使用 sbt-native-packager in conjunction with the plugins JavaAppPackaging
and DockerPlugin
to create the docker image without a Dockerfile
. There are some tutorials to create it on the web. Basically, you will need something like these lines on your build.sbt
file (example from my project).
enablePlugins(JavaAppPackaging, JavaServerAppPackaging, DockerPlugin, AshScriptPlugin)
// ####### Dockerfile settings #######
import NativePackagerHelper._
packageName in Docker := packageName.value
version in Docker := version.value
dockerExposedPorts := List(8001, 2551)
dockerLabels := Map("user" -> "you.email@gmail.com")
dockerBaseImage := "openjdk:jre-alpine"
dockerRepository := Some("docker.user.name")
defaultLinuxInstallLocation in Docker := "/usr/local"
daemonUser in Docker := "daemon"
mappings in Universal ++= directory( baseDirectory.value / "src" / "main" / "resources" )
// ####### Dockerfile settings #######
并在 project/plugins.sbt
文件中:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")
然后您在控制台上执行以下命令以在 target/docker/stage/Dockerfile
.
Dockerfile
sbt docker:stage
sbt docker:publishLocal
最后,为了解决这个问题,我将这个插件用于 'go-offline' 而不是 Maven 的:
<plugin>
<groupId>de.qaware.maven</groupId>
<artifactId>go-offline-maven-plugin</artifactId>
<version>1.2.8</version>
</plugin>
通过以下命令使用它:
mvn -B de.qaware.maven:go-offline-maven-plugin:resolve-dependencies
还在 scala-maven-plugin 中添加了禁用增量编译依赖项的配置:
<configuration>
<recompileMode>all</recompileMode>
</configuration>
所以完整的插件看起来像这样:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.4.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<recompileMode>all</recompileMode>
</configuration>
</plugin>