由于无法处理“ $ {project.artifactId}”:替换中缺少“:”,因此无法构建Docker映像

时间:2018-11-01 17:40:02

标签: maven docker docker-compose dockerfile

我正在尝试使用以下命令为Maven项目构建docker映像:mvn clean install -DskipTests -Pdocker

我有以下 Dockerfile

FROM openjdk:8-jre

ARG serviceuser=${project.artifactId}

##UPDATES AND INSTALL REQUIRED PACKAGES
RUN apt-get update && \
    apt-get install -y gettext-base sudo && \
    apt-get install -y iptables sudo && \
    adduser --shell /bin/bash ${serviceuser} && \
    adduser ${serviceuser} sudo && \
    echo "%sudo ALL=NOPASSWD: ALL" >> /etc/sudoers

USER ${serviceuser}

##MOVE AND COPY PROJECT FILES INTO CONTAINER
COPY ${project.build.finalName}.jar /home/${serviceuser}/

WORKDIR /home/${serviceuser}

pom.xml 文件包含以下一些内容:(为便于说明,使其更短)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.book.app</groupId>
  <artifactId>book-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>book-app</name>
  <url>http://maven.apache.org</url>
  <profiles>
    <profile>
      <id>docker</id>
      <build>
        <resources>
          <resource>
            <directory>docker</directory>
            <filtering>true</filtering>
            <targetPath>${project.build.directory}</targetPath>
          </resource>
        </resources>
        <plugins>
          <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.3.3</version>
            <executions>
              <execution>
                <id>default</id>
                <goals>
                  <goal>build</goal>
                  <goal>push</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <contextDirectory>${project.build.directory}</contextDirectory>
              <repository>test-img:2000/v1/${project.artifactId}</repository>
              <tag>${project.version}</tag>
              <tag>latest</tag>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.3.RELEASE</version>
  </parent>
  <dependencies>
    ...
  </dependencies>
  <build>
    ...
  </build>
</project>

构建时,它会显示以下错误消息...

原因:com.spotify.docker.client.exceptions.DockerException:无法处理“ $ {project.artifactId}”:替换中缺少“:”

[错误]无法处理“ $ {project.artifactId}”:替换中缺少':'

[INFO]内置失败

我将不胜感激,谢谢。

3 个答案:

答案 0 :(得分:0)

您必须在pom文件中更改<finalName>..</finalName>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.book.app</groupId>
  <artifactId>book-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>book-app</name>
  <url>http://maven.apache.org</url>
  <profiles>
    <profile>
      <id>docker</id>
      <build>
        <resources>
          <resource>
            <directory>docker</directory>
            <filtering>true</filtering>
            <targetPath>${project.build.directory}</targetPath>
          </resource>
        </resources>
        <plugins>
          <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.3.3</version>
            <executions>
              <execution>
                <id>default</id>
                <goals>
                  <goal>build</goal>
                  <goal>push</goal>
                </goals>
              </execution>
            </executions>
            <configuration>
              <contextDirectory>${project.build.directory}</contextDirectory>
              <repository>test-img:2000/v1/${project.artifactId}</repository>
              <tag>${project.version}</tag>
              <tag>latest</tag>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.3.RELEASE</version>
  </parent>
  <dependencies>
    ...
  </dependencies>
  <build>
    <finalName>${project.artifactId}</finalName>
    ...
  </build>
</project>

之后,您可以在Dockerfile中使用

FROM openjdk:8-jre

ARG serviceuser=${project.artifactId}

##UPDATES AND INSTALL REQUIRED PACKAGES
RUN apt-get update && \
    apt-get install -y gettext-base sudo && \
    apt-get install -y iptables sudo && \
    adduser --shell /bin/bash ${serviceuser} && \
    adduser ${serviceuser} sudo && \
    echo "%sudo ALL=NOPASSWD: ALL" >> /etc/sudoers

USER ${serviceuser}

##MOVE AND COPY PROJECT FILES INTO CONTAINER
COPY target/book-app.jar /home/${serviceuser}/

WORKDIR /home/${serviceuser}

我不确定为什么将serviceuser用作Dockerfile的ARG。

您可以阅读pom.xml的文档:https://maven.apache.org/pom.html

答案 1 :(得分:0)

只要变量名中包含某些非字母数字字符,Docker都会引发此误导性错误。

我认为它正在尝试将它们解释为指定bash样式default value substitution的语法。

为防止出现此错误,请从变量名中删除字符。

在您的示例中,是导致错误的.,对我来说是-,我必须用_替换。

答案 2 :(得分:0)

当在dockerfile中未定义ARG时,我已经看到了这一点。您可以将值定义为:

ARG JAR_FILE
ARG ARTIFACT_ID

然后在您的maven配置中,您将定义传递给构建的参数,如下所示:

<buildArgs>
   <JAR_FILE>${project.artifactId}-${project.version}.jar</JAR_FILE>
   <ARTIFACT_ID>${project.artifactId}</ARTIFACT_ID>
</buildArgs>

然后您可以像这样在dockerfile中引用它们:

FROM openjdk:8-jre

#Defined by the Maven Build Arguments in POM File
ARG JAR_FILE
ARG ARTIFACT_ID

# Add Maven dependencies (not shaded into the artifact; Docker-cached)
ADD target/dependency/BOOT-INF/lib      /usr/share/${ARTIFACT_ID}/lib
ADD target/dependency/META-INF          /usr/share/${ARTIFACT_ID}/META-INF
ADD target/dependency/BOOT-INF/classes  /usr/share/${ARTIFACT_ID}

# Add the service itself
ADD target/${JAR_FILE} /usr/share/${ARTIFACT_ID}/${JAR_FILE}

ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/${ARTIFACT_ID}/${JAR_FILE}"]

您最终的POM插件如下所示:

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.4.12</version>
    <executions>
        <execution>
            <id>default</id>
            <goals>
                <goal>build</goal>
                <goal>push</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <repository>${docker.image.prefix}/${project.artifactId}</repository>
        <tag>${project.version}</tag>       
        <buildArgs>
            <JAR_FILE>${project.artifactId}-${project.version}.jar</JAR_FILE>
            <ARTIFACT_ID>${project.artifactId}</ARTIFACT_ID>
        </buildArgs>
    </configuration>
</plugin>