I'm running a tomcat (tomcat:9-jre11) on docker, when launching it, it logs the following, then crashes :
Cannot find /usr/local/tomcat/bin/setclasspath.sh
This file is needed to run this program
My first issue was actually getting inside the container because I can't use docker exec on a crashed container, but I managed it by setting an entry point as /bin/bash in Rancher.
Now setclasspath.sh is very much in the /usr/local/tomcat/bin/ inside the container. It previously had all read and execution rights, I've set it to 777 just to be sure, still have the same issue. Same goes with changing the owner (tomcat seems to be using root, even if I launch the catalina.sh manually on another user, having changed the file owner). I used the heavy handed approch and set the whole damn folder as 777, and still the same :
drwxrwxrwx 1 root root 4096 Jun 29 14:53 .
drwxr-xr-x 1 root root 4096 Jun 29 14:31 ..
-rwxrwxrwx 1 root root 34699 Jun 2 21:08 bootstrap.jar
-rwxrwxrwx 1 root root 25523 Jun 29 14:00 catalina.sh
-rwxrwxrwx 1 root root 1664 Jun 2 21:08 catalina-tasks.xml
-rwxrwxrwx 1 root root 2007 Jun 28 03:01 ciphers.sh
-rwxrwxrwx 1 root root 25410 Jun 2 21:08 commons-daemon.jar
-rwxrwxrwx 1 root root 211777 Jun 2 21:08 commons-daemon-native.tar.gz
-rwxrwxrwx 1 root root 1932 Jun 28 03:01 configtest.sh
-rwxrwxrwx 1 root root 9110 Jun 28 03:01 daemon.sh
-rwxrwxrwx 1 root root 1975 Jun 28 03:01 digest.sh
-rwxrwxrwx 1 root root 3392 Jun 28 03:01 makebase.sh
-rwxrwxrwx 1 root root 3718 Jun 28 03:01 setclasspath.sh
-rwxrwxrwx 1 root root 1912 Jun 28 03:01 shutdown.sh
-rwxrwxrwx 1 root root 1914 Jun 28 03:01 startup.sh
-rwxrwxrwx 1 root root 46898 Jun 2 21:08 tomcat-juli.jar
-rwxrwxrwx 1 root root 5550 Jun 28 03:01 tool-wrapper.sh
-rwxrwxrwx 1 root root 1918 Jun 28 03:01 version.sh
I've looked at the catalina.sh script, the part which cause the issue is the following :
if [ -r "$CATALINA_HOME"/bin/setclasspath.sh ]; then
. "$CATALINA_HOME"/bin/setclasspath.sh
else
echo "Cannot find $CATALINA_HOME/bin/setclasspath.sh"
echo "This file is needed to run this program"
fi
The -r inside the condition is borked. I've read it looked if the file exists and is readable, it fill all conditions. I've added elif with -a and -f condition and the do return true, but the rights seems to be the issue despite them being set to 777 or not. I've add a whoami inside the script as well, and it's the root user, so not an issue of ownership.
The startup.sh script has a similar issue, with a -x condition, where it cannot find the catalina.sh ...
We just stumbled over this very problem today.
We have an Ubuntu 18.04 server that was upgraded from 16.04. The versions of the docker packages read:
docker-ce/now 5:19.03.1~3-0~ubuntu-xenial amd64
docker-ce-cli/now 5:19.03.1~3-0~ubuntu-xenial amd64
docker-compose/bionic,bionic,now 1.17.1-2 all
Kernel is: 4.15.0-154-generic x86_64
On this machine, running a current version of tomcat:9-jre11 [0] results in the same problem as depicted in your question.
To narrow it down, we just started a bash like this:
docker run -it --rm --entrypoint=/bin/bash tomcat:9-jre11
Now here comes the strange behavior you observed, which is completely unrelated to tomcat:
root@f338debf92f6:/usr/local/tomcat# [[ -r /bin/bash ]]
root@f338debf92f6:/usr/local/tomcat# echo $?
1
On any other machine we tested, the result is as expected, e.g.:
root@0083a80a9ec2:/usr/local/tomcat# [[ -r /bin/bash ]]
root@0083a80a9ec2:/usr/local/tomcat# echo $?
0
Unfortunately I was not able to reproduce the behavior using a freshly installed Ubuntu 18.04. I even downgraded the kernel version and installed docker from the xenial repo.
Trying to google a solution I found: https://github.com/alpinelinux/docker-alpine/issues/156#issuecomment-912645029
So I tried strace, and here the problem is visible:
On our Ubuntu 18.04:
...
read(255, "#!/bin/bash\n[[ -r /bin/bash ]]\n", 31) = 31
faccessat2(AT_FDCWD, "/bin/bash", R_OK, AT_EACCESS) = -1 EPERM (Operation not permitted)
read(255, "", 31) = 0
...
And on any other machine I tested:
...
read(255, "#!/bin/bash\n[[ -r /bin/bash ]]\n", 31) = 31
faccessat2(AT_FDCWD, "/bin/bash", R_OK, AT_EACCESS) = -1 ENOSYS (Function not implemented)
faccessat(AT_FDCWD, "/bin/bash", R_OK) = 0
read(255, "", 31)
...
Researching the faccessat2 system call shows that it should not return EPERM [1]. I could not quite pinpoint where this behavior is introduced - somewhere between glibc and seccomp, but it all boils down to the runtime being too old for this new syscall.
Here are the solutions we came up with:
tomcat:9.0.64-jre11-openjdk-slim-bullseye
worked fine.--privileged
switch. This circumvents the syscall privilege problem, but would be generally a bad ideaReferences