Start container service in a shell or not?

Hi guys, in which cases will you want to start the service in a shell and in which cases not?

ENTRYPOINT ['/bin/sh', '-c', 'curl', '--silent']

VS.

ENTRYPOINT ['curl', '--silent']

And security-wide, do you think there’s a difference?

The ENTRYPOINT instruction is used to declare the entrypoint script.
What you declare as entrypoint actualy looks like it belongs in the CMD instruction of the Dockerfile.

The command declared in ENTRYPOINT (usualy pointing to a bash script) is what is executed when the container is started. The command declared as CMD either becomes the argument to the command of the ENTRYPOINT - or in absense of an ENTRYPOINT instruction (including the hirarchie of all involved base images) the command declared as CMD will be executed when the container is started.

Security-wise it should make no difference. Process handling wise it makes a difference as in your first example PID1 will be /bin/sh. In your second example PID1 will be curl itself (absolut paths recommended here!)

The array style (which you already use) is recommended over the string style, the later will always wrap the value of the string with /bin/sh -c and will result in what I wrote about PID1 above.

I can see why absolute paths would be better, thanks! no ambiguity as to which executable is running.

But I theorize there might be a slight advantage of not running the executable in a shell, it makes it harder for the end user to break the immutability, this is just a theory I thought of, I have no idea.

With this entrypoint:

ENTRYPOINT ['/bin/sh', '-c', 'curl', '--silent']

You could more easily execute other things in a shell:

docker run <image id> google.com && rm -rf *

Of course if one really wants to break things up, nothing will stop him/her…

May I suggest to read the ENTRYPOINT section from here: Best practices for writing Dockerfiles | Docker Documentation

You don’t want to chain commands, neither in the CMD instruction of the image or when createing the container. You might want to read about the pid1 zombie reaper problem to get an understanding why don’t want to chain commands.

People usualy write entrypoint scripts with default behavior, that do some pre-execution tasks, like conditional execution of actions or renderding configuration changes based on environment variables.
They usualy have a exec "$@" at the and to execute whatever was provided as CMD instruction in the Dockerfile or as container argument when createing the container.

1 Like

Really interesting read, thanks for the links.
I’m halfway through reading about the pid1 problem.

BTW, I think this is still valid:

ENTRYPOINT ['curl', '--silent']

If your service is curl, and you always want it to run without showing progress meter or error messages, this is how you’d do it…
The CMD would be the URL.

Since you want to use the url as command, indeed: this is the way :wink: