Feedback

Chat Icon

Painless Docker - 2nd Edition

A Comprehensive Guide to Mastering Docker and its Ecosystem

Docker Containers
20%

TTY, Interactive and Detached Modes

When we create containers it's usually to run applications like web servers, databases, and API services. These containers are expected to run for a long time (hours, days, or even months). The reason why the hello-world container exits immediately is that its main process (the command that runs when the container starts) finishes its job and exits. This main process is defined in the image used to create the container. It's the init process of the container with PID 1, and it behaves like the init process of a Linux system. The lifecycle of a container is tied to the lifecycle of its init, just like a Linux system.

If you're running a Linux VM and run kill -TERM 1, the VM will shut down because its init process has exited. The same applies to containers. If the init process of a container exits, the container stops. If the container has no init at all, it will exit immediately. Later, depending on the restart policy of the container, it may be restarted automatically or remain stopped.

A container's main process should run in the foreground and remain attached to PID 1. Daemonizing or forking into the background causes PID 1 to exit, which will stop the container. This is a good practice because it allows Docker to manage the lifecycle of the container based on the state of its main process. For example, if the main process crashes, Docker can automatically restart the container if the restart policy is set accordingly.

Some images are designed to run a shell, such as bash, as the main process. In this case, the container remains running only as long as the shell process is active. For example, the Ubuntu image starts bash by default.

When you run docker run ubuntu without an interactive terminal, Bash starts in non-interactive mode and exits immediately, causing the container to stop. To keep such containers running, you must allocate a pseudo-TTY and attach standard input using the -it flags, which causes Bash to run interactively.

  • -i or --interactive: Keep STDIN open and attached.
  • -t or --tty: Allocate a pseudo-TTY so the process can run interactively.

Another alternative to -it is to run the container with a command that keeps running in the foreground, such as tail -f /dev/null or sleep infinity. This way, the container remains active without needing an interactive shell since the main process (tail, sleep, etc.) stays alive.

Test these examples to see the difference:

The container will exit immediately because Bash runs in non-interactive mode:

docker run --name exiting_ubuntu_container ubuntu
docker ps

The container will remain running because tail runs in the foreground:

docker run -d --name tailing_ubuntu_container ubuntu tail -f /dev/null
docker ps

The container will remain running because bash runs in interactive mode:

Painless Docker - 2nd Edition

A Comprehensive Guide to Mastering Docker and its Ecosystem

Enroll now to unlock all content and receive all future updates for free.

Unlock now  $31.99$25.59

Hurry! This limited time offer ends in:

To redeem this offer, copy the coupon code below and apply it at checkout:

Learn More