0

Following the suggestion on Execute a script before CMD (I needed to clear out a temp dir before a container is re-launched, to fix a bug), I modified my docker file from using a CMD, to entrypoint as follows:

ENTRYPOINT ["/app/entrypoint.sh", "/usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar"]

and in entrypoint file end after the rm -rf command:

exec "$@"

But docker is unable to launch the container, it exits, container log shows:

+ exec '/usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar' /app/entrypoint.sh: line 7: /usr/bin/java -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} -jar /app/app.jar: No such file or directory - what does this mean? what is wrong?

Carmageddon
  • 2,627
  • 4
  • 36
  • 56
  • Does `/usr/bin/java` exist in your image? – leeman24 Jan 10 '20 at 19:00
  • It has to, the image did not change, I only changed the code to run that command last via entrypoint script instead of `CMD`, so I can run `rm -rf` command before... But anyway I just logged into a container overriding the entrypoint script, and verified manually - the file is there: `lrwxrwxrwx 1 root root 22 Dec 14 18:14 /usr/bin/java -> /etc/alternatives/java` which points at `lrwxrwxrwx 1 root root 73 Dec 14 18:14 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre/bin/java` – Carmageddon Jan 10 '20 at 19:58

1 Answers1

1

You need to break the JSON-array-format command line into separate words. Since you’ve explicitly told Docker that the “command” part of this is a single word, it’s looking for a binary file in /usr/bin named java -Dlog4j.configurationFile=..., with the spaces and options and all as part of the filename, and not finding it.

You typically don’t want to embed the command you want to run in ENTRYPOINT, especially if you’re using this wrapper layout. Make ENTRYPOINT just be the name of the script ending in exec "$@"; it must use JSON-array syntax. Make CMD be the actual command you want to run, in whichever syntax is more convenient. (If you’re trying to expand environment variables, the shell-oriented syntax might be better.)

ENTRYPOINT ["/app/entrypoint.sh"]
CMD /usr/bin/java \
  -Dlog4j.configurationFile=/app/resources/LINUX/${LOG4J_FILE} \
  -Dpa.config=/app/resources/LINUX/${CONFIG_FILE} \
  -jar /app/app.jar

I’ve found this pattern to be sufficiently common and useful that I’d generally recommend using ENTRYPOINT only for this sort of wrapper script; prefer putting the command to start your application as CMD, even if you don’t have an entrypoint wrapper.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • It worked, thanks! I still don't understand this though.. its not clearly documented feature, feels more like a hack. – Carmageddon Jan 14 '20 at 15:01