Saffik
Saffik

Reputation: 1013

Unable to build docker image due to failed to process "${project.artifactId}": missing ':' in substitution

I am trying to build a docker image for a maven project with the command: mvn clean install -DskipTests -Pdocker

I have the following 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}

The pom.xml file has some of the following contents: (Have made it shorter just for explaination)

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

When i build, it gives me the following error message...

Caused by: com.spotify.docker.client.exceptions.DockerException: failed to process "${project.artifactId}": missing ':' in substitution

[ERROR] failed to process "${project.artifactId}": missing ':' in substitution

[INFO] BUILD FAILURE

I would appreciate any hints or help, thank you.

Upvotes: 2

Views: 9664

Answers (3)

DaCrazyCoder
DaCrazyCoder

Reputation: 51

I've seen this when the ARG is not defined in the dockerfile. You can define your value as:

ARG JAR_FILE
ARG ARTIFACT_ID

Then in your maven configuration, you will define the argument passed to the build as such:

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

You can then reference those in your dockerfile as such:

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}"]

Your final POM Plugin would look something like:

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

Upvotes: 1

JShorthouse
JShorthouse

Reputation: 1670

Docker throws this misleading error whenever you have certain non alpha-numeric characters in your variable name.

I assume that it is trying to interpret them as syntax to specify bash style default value substitution.

To prevent this error, remove the character from your variable name.

In your example it is the . causing the error, for me it was a - which I had to replace with an _.

Upvotes: 3

khmarbaise
khmarbaise

Reputation: 97487

You have to change the <finalName>..</finalName> in your pom file:

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

afterwards you can use in your 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}

I'm not sure why you use serviceuser as an ARG for the Dockerfile..

You can read in the documentation for the pom.xml: https://maven.apache.org/pom.html

Upvotes: 0

Related Questions