bmuschko/gradle-docker-plugin

Using exec in ENTRYPOINT prevents from passing arguments

BoD opened this issue ยท 8 comments

BoD commented

Expected Behavior

Running this command on a Docker built with the plugin:

docker run myord/myimage --foobar 

should pass the --foobar argument to the Java app

Current Behavior

The arguments are not seen by the Java app.

Context

This used to work in version 8.1.

I may be wrong, but I believe this is due to using exec introduced in this commit.

Maybe is there another way to easily pass arguments, that I'm not aware of?

Steps to Reproduce (for bugs)

  • My build.gradle.kts is visible here.
  • The line in the generated Docker file in version 8.1 was: ENTRYPOINT ["java", "-Xms16m", "-Xmx128m", "-cp", "/app/resources:/app/classes:/app/libs/*", "MainKt"]
  • With the latest 9.x version it looks like ENTRYPOINT exec java $JAVA_OPTS -Xms16m -Xmx128m -cp /app/resources:/app/classes:/app/libs/* MainKt
  • After running ./gradlew dockerPushImage and running for instance docker run bodlulu/woob-bank-slack -w /usr/local/bin, my app complains about the missing -w.

Your Environment

A Kotlin JVM app.

My build.gradle.kts is visible here.

The repository seems to be private. I get a 404 when trying to open the URL.

After running ./gradlew dockerPushImage and running for instance docker run bodlulu/woob-bank-slack -w /usr/local/bin, my app complains about the missing -w.

Can you provide me with some background information on why you want to change the workdir? It is already set by the generated Dockerfile. I am trying to understand your use case.

BoD commented

The repository seems to be private.

Woops, so sorry - my mistake! I've just fixed the visibility, the URL should be good now.

Can you provide me with some background information on why you want to change the workdir? It is already set by the generated Dockerfile. I am trying to understand your use case.

That was just an example actually but my app accepts a bunch of arguments, for instance some tokens. All of them should be passed with various flags when running it.

You'd usually provide configuration data to an application running in a container via environment variables or by mounting a volume. For example, that's the common pattern in Kubernetes.

I guess the args property provided by the extension wouldn't work for you as do not want to hard-code the values (because they change for different runtime environments)?

BoD commented

You'd usually provide configuration data to an application running in a container via environment variables or by mounting a volume.

Environment variables are less convenient in my case as I'm using a utility to handle CLI arguments (argument type, cardinality and presence validation, automatic uaage/help generation, etc.)

Also ideally the same app could be used with or without Docker (I guess this would still be true when passing arguments with env vars, but it's so much more common to pass them on the command line for a regular CLI tool.)

I guess the args property provided by the extension wouldn't work for you as do not want to hard-code the values

Correct ๐Ÿ‘

I'll have to see if there's a way to provide JAVA_OPTS without using exec. Maybe using /bin/sh -c but I am not sure. Appending arguments via docker run probably only works if you use the array notation for the ENTRYPOINT instruction which does not work for JAVA_OPTS. I am not sure when I will get around to looking at this again. Happy to review a PR if you want to make a proposal.

Some options I see for your project:

  1. I looked at your build file. Given that you are making so many customization (e.g. the Dockerfile), I'd almost say go with writing your own tasks instead of using the convention plugin.
  2. Stick with the convention plugin but replace the generated ENTRYPOINT instruction with something that works better for your use case.
  3. Allow configuring your application with environment variables as a fallback.

Side note: There's no need to modify the generated Dockerfile like you do here. You can change the value of the baseImage property of the extension.

BoD commented

Thank you so much ๐Ÿ™

I'd like to try a PR but it's hard to find time these days - but I'll try!

You can change the value of the baseImage property of the extension

that makes much more sense ๐Ÿ˜ I guessed there had to be a simpler way but didn't find it. Thanks again.

BoD commented

I'll have to see if there's a way to provide JAVA_OPTS without using exec. Maybe using /bin/sh -c but I am not sure.

After testing, I can confirm that an entry point of this form works well:

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Xms16m -Xmx128m -cp /app/resources:/app/classes:/app/libs/* org.jraf.slackchatgptbot.MainKt $0 \"$*\""]

Arguments are passed to the Java program as expected.

I released v9.3.1 that reverts the change #1176.