3

I have built a Docker image for my Java application - https://bitbucket.org/ijabz/songkongdocker/src/master/Dockerfile

The last line is

CMD /opt/songkong/songkongremote.sh

the (simplified) contents of songremote.sh are

#!/bin/sh
umask 000
./jre/bin/java-jar lib/songkong-6.9.jar -r

and it works fine.

However I have a customer who wants to run songkong with the -m option and a path

e.g

#!/bin/sh
umask 000
./jre/bin/java-jar lib/songkong-6.9.jar -m /users/music
  1. So is there a way a single docker can allow for two different command to be run, or do I have to build another docker.

  2. Either way how do I allow /users/music to be provided by user

The full contents of songkongremote are a bit more complicated, since more options have to be passed to Java

#!/bin/sh umask 000 ./jre/bin/java -XX:MaxRAMPercentage=60 -XX:MetaspaceSize=45 -Dcom.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog -Dorg.jboss.logging.provider=jdk -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging -Dhttps.protocols=TLSv1.1,TLSv1.2 --add-opens java.base/java.lang=ALL-UNNAMED -jar lib/songkong-6.9.jar -r

Update I follows Cascaders answer and it has done something (look at Execution Command)

enter image description here

but songkong.sh is acting as if no parameters have been passed at all (rather than -r option passed).

songkong.sh (renamed from songkongremote.sh) now contains

#!/bin/sh
umask 000
./jre/bin/java  -XX:MaxRAMPercentage=60 -XX:MetaspaceSize=45 -Dcom.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog -Dorg.jboss.logging.provider=jdk -Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging -Dhttps.protocols=TLSv1.1,TLSv1.2 --add-opens java.base/java.lang=ALL-UNNAMED -jar lib/songkong-6.10.jar "$@"

and the end of Dockerfile is now

EXPOSE 4567

ENTRYPOINT ["/sbin/tini"]

# Config, License, Logs, Reports and Internal Database
VOLUME /songkong

# Music folder should be mounted here
VOLUME /music

WORKDIR /opt/songkong

ENTRYPOINT /opt/songkong/songkong.sh
CMD ["-r"]

I don't understand if okay that there are two entrypoints or the signifcance of the sbin/tini one

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351

3 Answers3

1

You may try to use ENTRY point for the command, and CMD only for arguments

ENTRYPOINT ["/sbin/tini", "/opt/songkong/songkongremote.sh" ]

CMD [] # Arguments are passed here

You also need to handle arguments in your .sh file:

#!/bin/sh
umask 000
./jre/bin/java-jar lib/songkong-6.9.jar "$@"
andreoss
  • 1,570
  • 1
  • 10
  • 25
1

So is there a way a single docker can allow for two different command to be run, or do I have to build another docker.

Yes, you can handle this using single Dockerfile base on command with help of entrypoint.

entrypoint.sh

#!/bin/sh
umask 000
if [ "$1" == "-m" ];then
    echo "starting container with -m option"
    ./jre/bin/java-jar lib/songkong-6.9.jar "$@"
else
    ./jre/bin/java-jar lib/songkong-6.9.jar -r
fi

so if the docker run command look like this

docker run -it --rm myimage -m /users/music

it will execute first condition

But if [ "$1" == "-m" ] this will break if user pass like "-m /users/music" in double-quotes, as the condition only checking for first argument. you can adjust this accordingly.

So the Dockerfile will only contain entrypoint

ENTRYPOINT ["/opt/songkong/songkongremote.sh"]

Or you can CMD specify in Dockerfile

ENTRYPOINT ["/opt/songkong/songkongremote.sh"]
CMD ["-m", "/song/myfile]"

update:

You can not define two entrypoint per docker image, the first will be ignore.

Now to process to argument from CMD you should use array type syntax otherwise it will seems empty

ENTRYPOINT ["/opt/songkong/songkong.sh"]
CMD ["-r"]
Adiii
  • 54,482
  • 7
  • 145
  • 148
  • thx looks good, but would should end of docker file itself now look like ? – Paul Taylor Jul 10 '20 at 10:50
  • updated answer. `ENTRYPOINT ["/opt/songkong/songkongremote.sh"]` – Adiii Jul 10 '20 at 10:52
  • any luck or attemp? – Adiii Jul 10 '20 at 14:23
  • Hi, I have tried the very simailr answer from Cascader and it doesnt seem to be quite working (updated question with results) – Paul Taylor Jul 23 '20 at 13:05
  • 1
    updated. coincidence is I also looking in to your new question :D – Adiii Jul 23 '20 at 13:15
  • Thankyou did not understand the significance of the brackets. Okay now works (sort of), if I specify -h it shows the command help and then stops as expected. But if I pass-m /users/music to Execution Command/Command it runs but Synology will not let me access logs or terminal I guess because long running process, but if instead I pass -m /users/music & to run in background then it fails to launch with 'run command format' error ? – Paul Taylor Jul 23 '20 at 14:22
  • 1
    Sorry, actually seems to be workmng now okay, i can acces logs and terminal and I can stop it by pressing Cntl-C in the terminal. Okay thankyoufoir your help and accepting your answer as correct. – Paul Taylor Jul 23 '20 at 14:32
0

You can switch to ENTRYPOINT instead of CMD. Your docker file will look like:

...
ENTRYPOINT [ "/opt/songkong/songkongremote.sh" ]
...

Your customers would then run your image as:

docker run img -r

or

docker run img -m /users/music

You can even alter your bash script to accept arguments and pass those arguments using the same method.

If you need to provide default arguments and the ability to override them on demand, the following approach will work:

Dockerfile:

...
ENTRYPOINT [ "/opt/songkong/songkongremote.sh" ]
CMD ["-r"]
...

Your modified script:

#!/bin/sh 
umask 000 
./jre/bin/java \
-XX:MaxRAMPercentage=60 \
-XX:MetaspaceSize=45 \
-Dcom.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog \
-Dorg.jboss.logging.provider=jdk \
-Djava.util.logging.config.class=com.jthink.songkong.logging.StandardLogging \
-Dhttps.protocols=TLSv1.1,TLSv1.2 \
--add-opens java.base/java.lang=ALL-UNNAMED \
-jar lib/songkong-6.9.jar "$@"

Then, when customers run docker run img the CMD parameter will kick-in, but when they run docker run img -m /users/music the entrypoint command will be executed with the provided arguments.

Tasos P.
  • 3,994
  • 2
  • 21
  • 41
  • okay, thanks. But can I have a default because majority of customers run on Synology or Qnap nas so they dont invoke docker itself with commands, so I want the usual case to continue working without them having to actively chnage anything – Paul Taylor Jul 10 '20 at 09:18
  • 1
    I have updated my answer @PaulTaylor. Also check [this](https://stackoverflow.com/a/21564990/1505146) which explains the mechanism. – Tasos P. Jul 10 '20 at 10:37
  • 1
    ok, thx. sorry I simplified the original .sh script but its actually a bit more complex than that, Ive updated question, also note the umask cmd is required as well – Paul Taylor Jul 10 '20 at 10:46
  • That's ok, I can update my answer to use your script. andreoss's answer already covered that – Tasos P. Jul 10 '20 at 10:47
  • Hi, I have tried it and it doesnt seem to be quite working (updated question with results) – Paul Taylor Jul 23 '20 at 13:04
  • Please correct your syntax: it should be `ENTRYPOINT ["/opt/songkong/songkong.sh"]`, not `ENTRYPOINT /opt/songkong/songkong.sh` – Tasos P. Jul 23 '20 at 15:12
  • You can use [this](https://gist.github.com/tpapad28/ed3b4a383b5fe768e5bf98290e4e18d5) for reference – Tasos P. Jul 23 '20 at 15:16