I have a Dockerfile
that ends with:
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Now I want to run some initialisation from a shell script before that. So I have to refactor that to:
ENTRYPOINT[ /entrypoint.sh]
With:
!#/bin/bash
echo "some init"
#TODO
#ENTRYOINT["java", "org.springframework.boot.loader.JarLauncher"]
Question: how can I actually simulate the java entrypoint inside the shell script?
CodePudding user response:
ShellScript can be edited to run normal Java file.
From docker documentation:
If you need to write a starter script for a single executable, you can ensure that the final executable receives the Unix signals by using exec
!#/bin/bash
echo "some init"
#Execute using linux 'exec' Java launcher
exec java org.springframework.boot.loader.JarLauncher
CodePudding user response:
TL;DR: if the entrypoint wrapper ends with the line exec "$@"
, then it will run the image's CMD
. If you change the ENTRYPOINT
you have now to CMD
then you won't have to hard-code it in the script.
In the plain Dockerfile as you have it now, you can change ENTRYPOINT
to CMD
with no effect on how you use the container.
FROM openjdk:17
...
# not ENTRYPOINT
CMD ["java", "org.springframework.boot.loader.JarLauncher"]
On its own, this gives you some flexibility; for example, it's straightforward to peek inside the container, or to launch an interactive shell instead of the normal container process.
docker run --rm my-image ls /app
docker run --rm -it my-image sh
Now, if you have CMD
this way, you can add an ENTRYPOINT
wrapper script to it fairly straightforwardly. The CMD
is passed to the ENTRYPOINT
as additional arguments and the shell invocation exec "$@"
will run whatever is passed as the CMD
.
#!/bin/sh
# entrypoint.sh
echo "some init"
touch /init-has-happened
exec "$@"
Importantly, this works with the alternate docker run
commands I showed above. The alternate docker run
command replaces the Dockerfile CMD
but leaves the ENTRYPOINT
wrapper intact, so the alternate command gets run in the exec "$@"
line at the end.
docker run --rm my-image ls -l /init-has-happened
# the file will exist because the entrypoint wrapper creates it