How do I detect the interactive flag in a container?

At build time, you won't know what the runtime environment will look like. So there's no way to modify the RUN statements based on the -it flags or lack there of, we don't have time travel to look into the future for that, and the same image could be run multiple times with different flags.

You could do this within the entrypoint script. /dev/stdin which is mapped for interactive containers points to /proc/self/fd/0 which will point to different things based on whether you have -i, -it, or neither:

$ docker run -it --rm busybox ls -al /dev/stdin
lrwxrwxrwx    1 root     root            15 Jun 18 14:43 /dev/stdin -> /proc/self/fd/0

$ docker run -it --rm busybox ls -al /proc/self/fd/0
lrwx------    1 root     root            64 Jun 18 14:43 /proc/self/fd/0 -> /dev/pts/0

$ docker run -i --rm busybox ls -al /proc/self/fd/0
lr-x------    1 root     root            64 Jun 18 14:50 /proc/self/fd/0 -> pipe:[9858991]

$ docker run --rm busybox ls -al /proc/self/fd/0
lrwx------    1 root     root            64 Jun 18 14:43 /proc/self/fd/0 -> /dev/null

So if you stat the link to see if it's going to /dev/null or not, that would give you the answer to the question you asked.


Side note, if you only care about the -t, there's another check in shell you can run, [ -t 0 ], e.g.:

$ docker run -it --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
tty

$ docker run -i --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
no tty

$ docker run --rm busybox /bin/sh -c 'if [ -t 0 ]; then echo tty; else echo no tty; fi'
no tty

However, best practice with docker is to run the app itself in the foreground, as pid 1. And if you need to enter the container for debugging in a development environment, use docker exec for that. Your entrypoint then becomes:

ENTRYPOINT [ "/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh", "run" ]

And by doing that, you avoid an extra shell in pid 1 that could block container stop signals from gracefully stopping the app.

Then to debug, you'd exec after the run, using the container name:

docker container run -dp 8080:8080 -n tomcat-app <mydockername>
docker container exec -it tomcat-app /bin/sh

You don't need the start.sh at all.

Just use CMD directive as follows.

CMD ["/usr/local/apache-tomcat-v8.5.55/bin/catalina.sh", "run"]

Both the following command will start tomcat

docker run -it -p 8080:8080 <imagename> 

docker run -p 8080:8080 <imagename>

In case you want to debug something inside the container and want to access container shell, you can start a container and run bash as follows

docker run -it <imagename> bash 

This will override the defaut CMD with bash.


You can also replace CMD with ENTRYPOINT in the above suggestion but then if you want to access the container shell you have to do as follows -

docker run --entrypoint bash -it <imagename>

You can also look at official tomcat images and their dockerfiles here - https://hub.docker.com/_/tomcat