Hien Le
Hien Le

Reputation: 301

How to run docker container with custom variable (Built with Jenkins)

I'm trying to run a docker container that uses maven to deploy a java application Without using docker, the command that I use to deploy is "java -jar app-v0.1.jar"

Since the version of my application tends to change, (app-v0.1, v0.2 ...) what I usually do is running "java -jar *.jar" (There's always only 1 .jar file in the working folder). This works locally.

However, this seems to be unable to apply when building a Docker container. Here's my dockerfile


FROM openjdk:8

WORKDIR /app

COPY *.jar .

CMD ["java", "-jar", "*.jar"]

EXPOSE 8181


I can build the docker image from that Dockerfile. But when I try to run the container, I always get the Error: Unable to access jarfile *.jar.

I also tried:

COPY target/*.jar .

RUN file=`find . -name "*.jar" -exec basename {} \;`

CMD ["java", "-jar", "${file}"]

which returns Error: Unable to access jarfile ${file}

If I change the "*.jar" to a specific name, for example

CMD ["java", "-jar", "app-v0.1.jar"]

everything works normally. But clearly I don't want to change my Dockerfile every time there's a code update in my app.

Is there a way in which I can put variables in the Dockerfile, something like "

CMD ["java", "-jar", "${filename}.jar"] "?

(If this helps: I'm using Jenkins pipeline to automate the docker building process)

Upvotes: 0

Views: 1329

Answers (2)

atline
atline

Reputation: 31664

Solution 1:

Use ARG, see this:

FROM openjdk:8

ARG filename
ENV jarname=${filename}

WORKDIR /app

COPY *.jar .

CMD java -jar ${jarname}

EXPOSE 8181

The use docker build --build-arg filename=a.jar xxx

Solution 2:

Use ENV, see this:

FROM openjdk:8

ENV jarname=""

WORKDIR /app

COPY *.jar .

CMD java -jar ${jarname}

EXPOSE 8181

Pass env to when container run docker run -e jarname=a.jar xxx

Solution 3:

Make * work in shell:

FROM openjdk:8

WORKDIR /app

COPY *.jar .

CMD java -jar *.jar

EXPOSE 8181

Upvotes: 0

Mihai
Mihai

Reputation: 10767

I recommend to use a multi-stage build.

Your Dockerfile should be:

FROM maven:3.6.0-jdk-8 as build

ARG BUILD_PROFILE=prod

WORKDIR /apps

COPY . .
RUN mvn --activate-profiles ${BUILD_PROFILE} clean install

FROM openjdk:8-jre
COPY --from=build /apps/target/*.jar ./
COPY startup.sh ./

RUN chmod +x ./*.sh
ENTRYPOINT ["/startup.sh"]

And startup.sh:

#!/usr/bin/env bash
java -Dspring.profiles.active=${RUN_PROFILE} -jar /app*.jar

This way you also build your application when you do a docker build.

NOTE you can also use the command in startup.sh as your entrypoint but I find it cleaner this way.

Upvotes: 1

Related Questions