Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
339 views
in Technique[技术] by (71.8m points)

maven - Building Scala project with docker's Multi-Stage

I'm trying to build a scala project with docker Multi-Stage ability.

For starter, this is my dockerfile:

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

I noticed that after finishing the resolve-dependencies part, maven still trying to download dependencies on install stage. The errors that I get are related to the scala-maven-plugin that looking for non-existing dependencies that didn't fetched in the resolving stage. The errors looks like this:

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.

Even adding this dependency isn't enough because it fails on another dependecies.

The plugin in the POM looks like that:

        <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>

Seems like the plugin doesn't stop there and download everything again. Thanks guys..


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Like there is a comment on your question it is better to use sbt as a first citizen build tool for Scala. Particularly I suggest using the 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" -> "[email protected]")
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 #######

and at the project/plugins.sbt file:

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.6")

Then you execute the following commands on your console in order to create the Dockerfile at target/docker/stage/Dockerfile.

sbt docker:stage
sbt docker:publishLocal

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...