无法通过在Docker镜像中使用sh文件执行Maven命令

huangapple go评论82阅读模式
英文:

Unable to execute the maven command by using the sh file in docker image

问题

我正在使用包含所有Maven配置、密钥、Maven命令等内容的sh文件。我希望能够从Dockerfile内部执行此sh文件,以便在运行容器时执行sh文件。

以下是我的Dockerfile的外观:

# 使用Alpine JDK
FROM somewhere.docker.hub/build/alpine:latest AS fetch

# 作为构建工具的MVN
FROM somewhere.docker.hub/build/maven:3.5.3-jdk-8 AS build

# 用于从Nexus存储库下载依赖项的settings.xml
ARG MVN_SETTINGS=settings.xml

# 定义当前的工作目录
WORKDIR /usr/src/app

# 将pom.xml复制到工作目录
COPY pom.xml /usr/src/app

COPY ${MVN_SETTINGS} /usr/src/app/settings.xml

# 下载软件包并使其在Docker镜像中缓存
#RUN mvn -B -f ./pom.xml -s settings.xml dependency:resolve

# 将源代码复制到工作目录
COPY . /usr/src/app

# 运行sh文件
#RUN chmod a+x /usr/src/app/DockerTest.sh

# 未使用DockerTest.sh文件的完整路径,因为它已经位于如上所述的工作目录中
RUN chmod a+x DockerTest.sh

DockerTest.sh文件的内容如下:

#!/bin/sh
mvn clean install
mvn test

当我创建Docker镜像并运行该镜像时,它显示以下错误。尽管我尝试了许多方法,但仍然无法解决此错误。

"此构建未指定任何目标。您必须指定有效的生命周期阶段或以::[:]:格式的目标。可用的生命周期阶段包括:validate、initialize、generate-sources、process-sources、generate-resources、process-resources、compile、process-classes、generate-test-sources、process-test-sources、generate-test-resources、process-test-resources、test-compile、process-test-classes、test、prepare-package、package、pre-integration-test、integration-test、post-integration-test、verify、install、deploy、pre-clean、clean、post-clean、pre-site、site、post-site、site-deploy。-> [帮助 1]"

英文:

I am using the sh file which contains all the maven configuration, secret keys, maven command and all, I I want to execute this sh file from inside the Dockerfile so that when I run the container sh file will execute.

this is how my Docker file looks like:

#using alpine jdk
FROM somewhere.docker.hub/build/alpine:latest AS fetch

#MVN as build tool
FROM somewhere.docker.hub/build/maven:3.5.3-jdk-8 AS build

#Settings.xml for downloading dependencies from nexus repository
ARG MVN_SETTINGS=settings.xml

#Defining the current working repository
WORKDIR /usr/src/app


#Coping the pom.xml into working directory
COPY pom.xml /usr/src/app

COPY ${MVN_SETTINGS} /usr/src/app/settings.xml

# Download the package and make it cached in docker image
#RUN mvn -B -f ./pom.xml -s settings.xml dependency:resolve


#Coping the source code into the working repository
COPY  . /usr/src/app


#Run the sh file
#RUN chmod a+x /usr/src/app/DockerTest.sh

# Not using the full path of DockerTest.sh file because it is already in the work directory as defined above
RUN chmod a+x DockerTest.sh

DockerTest.sh file looks like this.

#!/bin/sh
mvn clean install
mvn test

when I create the docker image and run the image, it shows this error.
I have tried lots of things it is still not working, it shows this error

No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]

答案1

得分: 1

首先,你不能通过在多个FROM行之后连续使用它们来合并两个Docker镜像。之所以可以指定多个FROM行,是为了支持多阶段构建

其次,如果你没有使用这行命令:

RUN mvn -B -f ./pom.xml -s settings.xml dependency:resolve

你可能也可以将这行注释掉:

COPY pom.xml /usr/src/app

因为你的POM将与其余的源代码一起被复制。

第三,根据你的Dockerfile,你的工作目录中有几个settings.xml文件,并且你想根据构建参数选择一个。然而,如果你有settings.xmlsettings.prod.xml,并且你将MVN_SETTINGS设置为settings.prod.xml,那么这行命令会覆盖/usr/src/app/settings.xml

COPY  . /usr/src/app

使用settings.xml

第四,mvn clean install也会运行测试,所以没有必要单独执行mvn test

最后,关于你注意到的问题。我不确定当你运行镜像时你期望发生什么,但是你在Dockerfile中没有指定任何入口点或要运行的命令,因此你的镜像会继承其基础镜像的默认值。现在假设你实际上是指 docker.io/library/maven:3.5.3-jdk-8 而不是 somewhere.docker.hub/build/maven:3.5.3-jdk-8,那么命令是 mvn,入口点是 /usr/local/bin/mvn-entrypoint.sh(在这里查看略新的镜像的Dockerfile链接在这里)。

综上所述,假设你希望在运行镜像时运行 DockerTest.sh,你的 Dockerfile 应该如下所示:

FROM maven:3.5.3-jdk-8
ARG MVN_SETTINGS=settings.xml
WORKDIR /usr/src/app
COPY . .
COPY ${MVN_SETTINGS} settings.xml
RUN chmod a+x DockerTest.sh
CMD ./DockerTest.sh

另外,如果你实际上想在构建过程中使用你的 settings.xml,你需要将你的 DockerTest.sh 更改为:

#!/bin/sh
mvn --settings /usr/src/app/settings.xml clean install

你还可以通过以下方式来避免不必要地两次复制同一个文件:

FROM maven:3.5.3-jdk-8
ARG MVN_SETTINGS=/usr/src/app/settings.xml
ENV MVN_SETTINGS=${MVN_SETTINGS}
WORKDIR /usr/src/app
COPY . .
RUN chmod a+x DockerTest.sh
CMD ./DockerTest.sh

以及

#!/bin/sh
mvn --settings "$MVN_SETTINGS" clean install
英文:

First of all you cannot combine two Docker images by using multiple FROM lines one after another. The reason it's even possible to specify more than one is to enable multi-stage builds.

Second, if you're not using this line:

RUN mvn -B -f ./pom.xml -s settings.xml dependency:resolve

you may as well comment this one too:

COPY pom.xml /usr/src/app

since your POM will be copied along with the rest of the source code.

Third, judging from your Dockerfile, you have several settings.xml files in your working directory and you want to choose one base on a build argument. However, if you have say settings.xml and settings.prod.xml and you set MVN_SETTINGS to settings.prod.xml, then /usr/src/app/settings.xml will be overwritten by this line:

COPY  . /usr/src/app

with settings.xml.

Fourth, mvn clean install runs tests as well, there is no need to do mvn test separately.

Finally, for the issue you have noticed. I'm not sure what you expect to happen when you run the image, but you did not specify any entrypoint or command to be run in your Dockerfile, so your image inherits the default one from its base. Now assuming that by somewhere.docker.hub/build/maven:3.5.3-jdk-8 you actually mean docker.io/library/maven:3.5.3-jdk-8 then the command is mvn and the entrypoint is /usr/local/bin/mvn-entrypoint.sh (see Dockerfile for a slightly newer image here).

With all that said, assuming you want to run DockerTest.sh when your image is run, your Dockerfile should look like this:

FROM maven:3.5.3-jdk-8
ARG MVN_SETTINGS=settings.xml
WORKDIR /usr/src/app
COPY . .
COPY ${MVN_SETTINGS} settings.xml
RUN chmod a+x DockerTest.sh
CMD ./DockerTest.sh

Also, if you actually want to use your settings.xml during build you need to change your DockerTest.sh to:

#!/bin/sh
mvn --settings /usr/src/app/settings.xml clean install

You could also remove unnecessary copying the same file twice by doing:

FROM maven:3.5.3-jdk-8
ARG MVN_SETTINGS=/usr/src/app/settings.xml
ENV MVN_SETTINGS=${MVN_SETTINGS}
WORKDIR /usr/src/app
COPY . .
RUN chmod a+x DockerTest.sh
CMD ./DockerTest.sh

and

#!/bin/sh
mvn --settings &quot;$MVN_SETTINGS&quot; clean install

huangapple
  • 本文由 发表于 2020年9月22日 00:31:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63996424.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定