Cannot start catalina from entrypoint, container exit code 37

I currently have this setup which works:

Dockerfile:
ENTRYPOINT [ "/start.sh" ]`




start.sh:
#Also redirects stdout and stderr to catalina log file. This will essentially keep the container alive.
/usr/local/tomcat/bin/catalina.sh run &> "/usr/local/tomcat/logs/catalina.out"

However, I would like to avoid all the logs being outputted to catalina.out. However, if I remove that part, the container will simply just exit immediatly. I then learned that it should be possible to avoid that using ENTRYPOINT. So I have tried this (and many other things it feels like)

Dockerfile:
#First run the startup script and then start tomcat
ENTRYPOINT ["/bin/sh", "-c", "/start.sh && /usr/local/tomcat/bin/catalina.sh run"]




start.sh:
printf "Start script done\n"

When I run the container, I can see that “Start script done” is printed. Tomcat is started and my application starts to load. But then the container shuts down with exit code 37. What am I doing wrong here? I cannot seem to be able to figure it out. I understand that code 37 has to do with memory? It does not make any sense to me as my previous setup always worked completely fine without memory issues.

If you want to customize the ENTRYPOINT, CMD and SHELL instructions, you can learn about that from my blog post and video:

It also looks like you are not using the official tomcat image which has a different way to run catalina.

And if you could edit start.sh why didn’t you just remove &> "/usr/local/tomcat/logs/catalina.out" from the end?

I did try and remove
&> "/usr/local/tomcat/logs/catalina.out"
From the end but then the container would just exit immediatly. It is my understand that catalina.sh run will run catalina in the foreground, and thus docker should not kill the container.

From ChatGPT:

In Bash, &> is a shorthand for redirecting both standard output (stdout ) and standard error (stderr ) to the same destination.

So it should be removable without any other impact from the script file. If an error occurs the container will still terminate.

For your second approach, you might try to separate all params into separate quoted blocks (instead of using spaces), like you did at the beginning of the line.

Exactly as @bluepuma77 wrote. That is just redirection. If removing it makes the container stop, then something else is going on too. A syntax error for example.

Docker won’t kill the container. The process can stop in the container an without a process, there is no container. Since the official tomcat image uses cataline.sh run too, that should be fine unless catalina.sh can be different when it is not made for a containerized application. How did you install tomcat in the image?

I didn’t have time last time to give you more details, but the blogpost I linked should tell you everything you need to know about changing the entrypoint. For example, never do something like this:

ENTRYPOINT ["/bin/sh", "-c", "command"]

The shel will not forward stop signals so the container cn’t handle docker stop and it will be killed without waiting for the process to properly stop and finish their job. If you do use something like that, also use exec to replace the first process by a new one. In your case, catalina:

ENTRYPOINT ["/bin/sh", "-c", "/start.sh && exec /usr/local/tomcat/bin/catalina.sh run"]

That way your start script runs in the shell and the shell will be replaced with catalina being the only process running on the container and can handle stop signals directly. On the other hand, entrypoints and the command would be concatenated, but if your entrypoint is a parameter of a shell, every command will be ignored, so that’s the second reason why you shouldn’t do this and use a shell script instead.

This is why docker-entrypoint.sh exists usually so it can handle arguments and at the end of the scrip, it can still exec catalina with the arguments passed to it.

As for error code 37 I have no idea why that would happen.

About @bluepuma77’s recommendation

Since the your entrypoint is a shell with the commands as a single argument, unfortunately there is no way to pass the command after -c as a json since the shell expects a single string…