How to Keep Docker Container Running

Docker containers are generally designed to run a specific task or process and will remain active for the duration of that process. When the process finishes, the container exits. However, there are scenarios where you might want to keep the Docker container running indefinitely. This could be for debugging, development, or other operational reasons.

In this post, we'll first understand why Docker containers exit and then explore four methods you can use to keep them running. Let’s get started!

Prerequisites

To follow along with the examples in this post, we recommend using KodeKloud’s Docker playground. This playground will provide you instant access to a Docker environment where you can run and manage containers. No need for you to install any software. With just one click, you'll be ready to start working with containers.

Alternatively, you can use Docker Desktop. If you don’t have Docker Desktop, you can download it from here. You can find the official installation guide by following this link.

Note that the commands provided in the examples below have been tested on KodeKloud’s Docker playground.

Try the Docker Run Lab for free:

Docker Run Lab
Docker Run Lab

Why Docker Containers Exit

In Docker, containers continue to run as long as the "main app" is active. The term "main app" refers to the primary application or process that is executed when the container starts. It's defined either in the container's Dockerfile using the CMD or ENTRYPOINT instructions or at runtime with the docker run command.

Here's what happens when you start a container:

  • Docker initiates the main application as the root process, which is assigned PID 1.
  • This root process oversees the container's lifecycle, meaning the container remains active as long as this process does.
  • Once the main process completes its execution (whether it finishes its task, or it's terminated for any other reason), the main process ends.
  • Docker then identifies that there are no active processes remaining in the container, signifying that the container's work is complete. Consequently, Docker proceeds with the cleanup and stops the container – the container exits.

Let’s demonstrate this with an example. Run the following command: 

docker run --name demo-1 ubuntu echo "Hello World"

After running the command, you’ll see the text Hello World printed on the console, as shown below:

Now, run the following command to list all Docker containers on your system (both running and stopped): 

docker ps -a

You’ll see the following output:

As you can see, the container has exited. This is due to the nature of the echo command itself. echo is a non-persistent command, meaning that it runs once, outputs its text to the console, and then terminates.

Since the echo command is the main process in this Docker container, assigned PID 1, the container relies on this process to remain active. As soon as the echo process finishes its execution, there are no more active processes to keep the container running. Docker recognizes that the main application's task is complete and that there's nothing else to do. Consequently, Docker stops the container, as its job is complete. This is why the container exits immediately after printing Hello World to the console.

4 Methods to Keep Docker Container Running

In the previous section, we learned that a Docker container exits immediately after its main, non-persistent command finishes execution. In this section, we'll explore four different methods you can use to ensure a Docker container keeps running indefinitely. 

#1 Using the sleep infinity command

A straightforward method to prevent a Docker container from exiting is to use the sleep infinity command. The sleep command is designed to pause command execution for a specified amount of time. By specifying infinity, you are effectively instructing the system to sleep indefinitely, thus preventing the container from shutting down, as there is always an active process.

Let’s see this in action. Run the following command:

docker run -d --name demo-2 ubuntu /bin/bash -c "echo 'Hello World'; sleep infinity"

In the command above: 

  • docker run is used to create and start a new container named demo-2 based on the Ubuntu image. 
  • /bin/bash -c executes a string of commands ("echo 'Hello World!'; sleep infinity") in the shell. The shell first runs echo 'Hello World' to print Hello World to the console, and after completing that command, it executes sleep infinity, which will keep the container running indefinitely since sleep infinity does not terminate on its own.

After running the command, you’ll see the following output:

Next, run the following command to list all Docker containers on your system: 

docker ps -a

As you can see, the demo-2 container is up and running.

Note: The reason we did not see Hello World in the console output is that the container is running in detached mode (-d flag), operating in the background. In detached mode, the output of the command the container runs is not displayed on the terminal. If you want to see what was logged to the console, you can retrieve the logs of the container. To do this, use the command docker logs <container_name>

#2 Using the tail -f /dev/null command

Another method to keep a Docker container running indefinitely is by using the tail -f /dev/null command.

Here's how it works:

  • tail is a Linux command that outputs the last part of files.
  • -f is an option that tells tail to "follow" the file's output. It keeps the tail command running and outputs any new content that is added to the file.
  • /dev/null is a special file that discards all data written to it.
  • When you combine tail -f with /dev/null, you're telling tail to follow a file that will never have any new content. Since /dev/null doesn't change, tail -f doesn't do anything except wait for new data, which never comes. This effectively puts tail into an idle state, and the container is kept alive.

Let’s see this in action. Run the following command:

docker run -d --name demo-3 ubuntu /bin/bash -c "echo 'Hello World'; tail -f /dev/null"

After running the command, you’ll see the following output:

Next, run the following command to list all Docker containers on your system: 

docker ps -a

You’ll get the following output: 

As you can see, the demo-3 container is up and running.

#3 Using the cat command (without passing any arguments)

The third option you can use to keep a Docker container running indefinitely involves the use of the cat command.

When you run cat without arguments, it reads from stdin (standard input). If no input is provided, cat simply waits indefinitely for it. This behavior can be leveraged to prevent the Docker container from exiting after a non-persistent command has finished its execution.

Let’s see this method in action. Run the following command: 

docker run -dt --name demo-4 ubuntu /bin/bash -c "echo 'Hello World'; cat"

Note: The reason we have added the -t flag in the command is that when the cat command is run without any arguments, it expects to be connected to a terminal. Without the -t flag, the cat command would not behave as expected, and the container would exit.

After running the command, you’ll see the following output:

Now, list the containers on your system by running the following command: 

docker ps -a

You’ll see the following output:

As you can see, the demo-4 container is up and running.

#4 Opening a shell session

Another effective technique to keep a Docker container running indefinitely is by opening a shell session within the container.  

Let’s see this method in action. Run the following command:

docker run -dt --name demo-5 ubuntu /bin/bash -c “echo ’Hello World’; /bin/bash"

Here, the /bin/bash command gets executed as the final step in the command sequence. By doing so, it initiates a bash shell session within the container. This is critical because, with the allocation of a terminal through the -t flag, the bash shell remains active, effectively waiting for further input. However, the container is not immediately visible to us since it operates in the background. This combination is what keeps the container running indefinitely, maintaining an active bash session in a non-interactive mode.

Note: The -i flag, which often accompanies -t, stands for "interactive," and allows you to keep stdin open even if not attached. It's this combination (-it) that you'd typically use to interact with the container. However, even without -i, just -t alone can be enough to keep the container running because the Docker daemon thinks there is an interactive session going on and waits for user input, which never comes, thus keeping the container alive.

After running the command, you’ll see the following output: 

Next, run the following command to see the list of containers on your system:

docker ps -a

You’ll see the following output:

As you can see, the demo-5 container is up and running as expected.

Conclusion

In this post, we explored four different methods to keep Docker containers running indefinitely. Each method serves the same primary purpose but does so in a different way. Depending on your specific requirements, you may find one method more suitable than the others. 

Interested in learning more about Docker? Check out the following courses from KodeKloud:

Docker Training Course for the Absolute Beginner | KodeKloud
Learn Docker with simple and easy hands-on Labs
  • This course will help you understand Docker using lectures and demos. You’ll get a hands-on learning experience and coding exercises that will validate your Docker skills.  Additionally, assignments will challenge you to apply your skills in real-life scenarios.
Docker Certified Associate Exam Course | KodeKloud
Prepare for the Docker Certified Associate Exam Course
  • This course covers all the required topics from the Docker Certified Associate Exam curriculum. The course offers several opportunities for practice and self-assessment. There are hundreds of research questions in multiple-choice format, practice tests at the end of each section, and multiple mock exams that closely resemble the actual exam pattern.