1

Consider the command:

ls [OPTION]... [FILE]...

Options come first, and then comes the file. However, somehow, I have no idea why, ls does not insists on this order. Therefore ls -la /home and ls /home -la produce identical output.

We can use this quirk to send options to a ls that knows its [FILE] argument.

FROM ubuntu:22.04
ENTRYPOINT ["ls", "/home"]

Then passing arguments is the same as passing options:

$ docker build -t test .
$ docker run test
$ docker run test -la
total 8
drwxr-xr-x 2 root root 4096 Apr 18 10:28 .
drwxr-xr-x 1 root root 4096 May 12 16:58 ..

However some programs insist on the order of options and arguments. For instance a .jar with a Spring server application:

This works as intended:

 java -jar -Dspring.profiles.active=ci backend.jar

This does not:

 java -jar backend.jar -Dspring.profiles.active=ci

The [COMMAND] and [ARG...] in docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...] seem to be appended to the entrypoint and not inserted.

Is there any way to pass options instead of arguments to a docker ENTRYPOINT?

Martin Drozdik
  • 12,742
  • 22
  • 81
  • 146
  • 1
    Also see [Understand how CMD and ENTRYPOINT interact](https://docs.docker.com/engine/reference/builder/#understand-how-cmd-and-entrypoint-interact) in the Dockerfile documentation, and discussion of the [container-as-command pattern](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#entrypoint). (Also the [recommendation for `CMD` to be a complete command](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#cmd) in the same document.) – David Maze May 13 '22 at 00:56

3 Answers3

1

Assuming you want to keep the java -jar backend.jar part, you can add a tiny shell script that takes the arguments you put at the end and passes them before. See the selected answer here for details on how to do that

Liel Fridman
  • 1,019
  • 7
  • 11
1

Everything that you use as CMD, may it be from the Dockerfile or when running the image, is passed to the ENTRYPOINT as arguments.

You can create a more sophisticated entrypoint, preferable via script.

#!/usr/bin/env sh

exec java -jar $@ backend.jar

I am using $@ which are all the args passed to the script, effectively the CMD.

Additionally, I am using exec to make the final java command run with process ID (pid) 1, so that it receives signals properly. For example SIGTERM.

The Fool
  • 16,715
  • 5
  • 52
  • 86
1

You can use CMD for this.

ENTRYPOINT ["java"]
CMD ["-jar", "-Dspring.profiles.active=ci", "backend.jar"]

This also allows you to change the parameters at runtime. E.g.

docker run <image> -jar -Dspring.profiles.active=debug backend.jar
Mikael Kjær
  • 670
  • 3
  • 6
  • The `ENTRYPOINT` _must_ be in JSON-array form `ENTRYPOINT ["java"]` for this to work. I wouldn't recommend just using an interpreter as the `ENTRYPOINT` here, but if you make the whole thing `ENTRYPOINT ["java", "-jar", "backend.jar"]` then any (`CMD`) arguments will be visible to the `main()` function. – David Maze May 13 '22 at 00:54
  • Sorry, I'm not a java guy so I'm not familiar with how arguments should go, but it seems in the original post that the profile needs to be in the middle. I fixed the `ENTRYPOINT`. Thanks. – Mikael Kjær May 13 '22 at 18:25