Docker containers are powerful tools for application isolation and deployment. However, understanding how to interact with a running container, particularly through a shell, can sometimes be tricky. This tutorial will explain how to launch an interactive shell within a Docker container and clarify the roles of ENTRYPOINT and CMD in defining container behavior.
Understanding the Basics
By default, a Docker container runs a process defined by the image’s configuration. When you run a container, that process starts and the container exits when the process finishes. To interact with a container, you need to start a shell within the container’s environment.
Running an Interactive Shell
The most common way to start an interactive shell session in a Docker container is using the docker run command with specific flags.
docker run -it --entrypoint bash <image_name>
Let’s break down these flags:
-ior--interactive: Keeps STDIN open even if not attached. This allows you to send input to the container.-tor--tty: Allocates a pseudo-TTY. This creates a terminal-like environment within the container, making the shell experience more intuitive.--entrypoint bash: Overrides the defaultENTRYPOINTdefined in the image’s Dockerfile. This is crucial because, by default, Docker executes theCMDinstruction using theENTRYPOINTas a wrapper. By explicitly settingENTRYPOINTtobash, we ensure thatbashitself becomes the primary process running inside the container, giving us an interactive shell.<image_name>: The name of the Docker image you want to use.
Example:
docker run -it --entrypoint bash docker/whalesay
This command will start a new container based on the docker/whalesay image and launch a bash shell inside it. You’ll then see a prompt where you can execute commands within the container’s environment.
Entering an Existing Container
Sometimes, you need to access a shell within a container that’s already running. The docker exec command is designed for this purpose.
docker exec -it <container_id_or_name> bash
<container_id_or_name>: The ID or name of the running container you want to access. You can find these usingdocker ps.bash: The command you want to execute within the container. In this case, it’sbashto start an interactive shell.
Example:
First, start a container in detached mode:
docker run -d --name mycontainer docker/whalesay
Then, enter the container:
docker exec -it mycontainer bash
Understanding ENTRYPOINT and CMD
The behavior of Docker containers is determined by the ENTRYPOINT and CMD instructions in the image’s Dockerfile. It’s important to understand how these two interact.
ENTRYPOINT: Defines the main executable that will be run when the container starts. Think of this as the "base" command.CMD: Provides default arguments to theENTRYPOINT. If you specify a command when running the container (e.g.,docker run <image> <command>), that command will override theCMDinstruction.
Here’s how it works:
- If an
ENTRYPOINTis defined, Docker effectively executes the following command:ENTRYPOINT <CMD>. - If no
ENTRYPOINTis defined, Docker executes theCMDinstruction directly.
By explicitly setting --entrypoint bash during docker run, we are overriding the default ENTRYPOINT (which might be defined in the image’s Dockerfile) and setting bash as the main executable. This allows us to get an interactive shell.
Inspecting ENTRYPOINT and CMD
You can inspect an image to see its ENTRYPOINT and CMD using the docker inspect command.
docker inspect <image_name> | jq '.[].Config.Entrypoint,.[].Config.Cmd'
This command will output the Entrypoint and Cmd configurations for the specified image. The jq tool is a lightweight and flexible command-line JSON processor that makes it easier to parse the output. If you don’t have jq installed, you can omit it, but the output will be more verbose.