Reputation: 20618
I am able to run arbitrary shell commands in a container created from docker/whalesay image.
$ docker run docker/whalesay ls -l
total 56
-rw-r--r-- 1 root root 931 May 25 2015 ChangeLog
...
However, I am unable to run bash
in a container created from this image:
$ docker run docker/whalesay bash
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ce600cc9904 docker/whalesay "bash" 5 seconds ago Exited (0) 3 seconds ago loving_mayer
Why did it not work? How can I make it work?
Upvotes: 389
Views: 646391
Reputation: 56478
If you docker run
without attaching a tty, and only call bash
, then bash finds nothing to do, and it exits. That's because by default, a container is non-interactive, and a shell that runs in non-interactive mode expects a script to run. Absent that, it will exit.
To run a disposable new container, you can simply attach a tty and standard input:
docker run --rm -it --entrypoint bash <image-name-or-id>
Or to prevent the above container from being disposed, run it without --rm
.
Or to enter a running container, use exec
instead:
docker exec -it <container-name-or-id> bash
In comments you asked
Do you know what is the difference between this and
docker run -it --entrypoint bash docker/whalesay
?
In the two commands above, you are specifying bash
as the CMD
. In this command, you are specifying bash
as the ENTRYPOINT
.
Every container is run using a combination of ENTRYPOINT
and CMD
. If you (or the image) does not specify ENTRYPOINT
, the default entrypoint is /bin/sh -c
.
So in the earlier two commands, if you run bash
as the CMD
, and the default ENTRYPOINT
is used, then the container will be run using
/bin/sh -c bash
If you specify --entrypoint bash
, then instead it runs
bash <command>
Where <command>
is the CMD
specified in the image (if any is specified).
EDIT May 2024
Responding to a recent question, updating with a bit more detail. How do you know what the ENTRYPOINT and CMD are?
You can inspect an image (and use something like jless
or jq
to easily find things in the JSON output, if desired). For example:
❯ docker inspect docker/whalesay | jq '.[].Config.Entrypoint,.[].Config.Cmd'
null
[
"/bin/bash"
]
Here we see the ENTRYPOINT is null
and the CMD
is ["/bin/bash"]
. In this case, Docker will execute the CMD with a system call.
The exact behaviors are in the Docker documentation. As of today this link will take you there, but the link might change in the future.
Upvotes: 735