Estimated reading time: 13 minutes
Last updated on November 8th, 2024 at 04:57 pm
Docker containers are designed to run a specific process and will keep Docker container running until that process is active. A container runs the main process defined in ENTRYPOINT
or CMD
in the Dockerfile. It’s best practice to keep one process per container so the container exits when the main process finishes.
In certain situations, such as debugging, development, or doing some operation, you might want to keep Docker container running even if the main process is finished. You can check How to Attach and Detach From a Docker Container
In this blog, let’s understand why Docker container exits and then investigate the various methods to keep them running indefinitely.
Table of Contents
What Happens When You Run a Docker Container?
Before jumping into to Docker container to keep running, you should understand what exactly happens when you run a Docker container.
When you launch a Docker container, it starts the execution of the primary process—the main task the container is built to perform. This process could be running a web server, running an application code, executing the batch, or simple shell commands.
Here’s the breakdown of what happens:
Primary Process Starts as PID 1:
Continuous Execution of the Main Process:
Container Shutdown on Process Completion:
Why Docker Containers Stop Running
Docker containers are designed to be lightweight compared with the traditional VM, hence it will be running only as long as the process they are instructed is executed and finished.
So when the process is finished, the container stops and that’s the default behavior. This behavior makes them efficient, but it can lead to unnecessary exits if you’re using it for ongoing tasks or you want to debug any of the unexpected exits.
Here are some of the common reasons why Docker containers may stop running:
It’s important to understand these causes to prevent unintended shutdown and ensure the Docker container keeps running for the intended duration.
Let’s understand the behaviour with and real-world example:
As we discussed what happens when you run a container, the reason for Docker to exit immediately is no longer a running process. The container should have the foreground process, running to keep Docker container running.
Let’s see how this thing works with an example by running an official Docker image hello-world
docker run hello-world
This will run the hello-world container echo out the output and exit.
Let’s run the following command to list all Docker containers:
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
64e3f531f641 hello-world "/hello" 3 seconds ago Exited (0) 2 seconds ago musing_lamport
The container has exited once it prints the Hello from Docker!
command.
Here the main process inside the Docker container running as PID1 is finished printing the output.
Once the task for the main process is finished, there are no more remaining tasks to execute that can keep Docker container running. The Docker daemon keeps monitoring this and once no main process is running it stops the container.
This is the reason why it exits Immediately after it starts and prints the Hello from Docker!
Common Method to Keep Docker Container Running
In the last section, we understand what happens when you run a container and why the Docker container exits Immediately after the main process finishes the execution.
Let’s check how you can keep Docker container running for debugging indefinitely.
1. Use the tail-f /dev/null Command
For a lightweight and efficient approach, you can run a command that continuously executes without needing user input.
You can keep the Docker container running indefinitely using tail -f /dev/null
when you run the container:
docker run -d --name tail-demo alpine tail -f /dev/null
Passing the tail -f /dev/null
with the docker run command enables the container to run the tail
as the main process.
To understand this, tail
if Linux commands to show the last line of files, but when you add -f
option, it will keep track of the new content added to the file and display.
So, when you use tail -f
with /dev/null
, it will wait for the data, but dev/null
always discard the content. As a result, your Docker container’s main process waits for the data that never comes and keeps Docker container running in an idle state.
Let’s verify that the container is still running:
docker ps -a
You can check the following output:
As you can see, the container tail-demo
running.
2. Use the Pseudo-TTY (Interactive mode)
You can use the Docker Pseudo-TTY method to keep Docker container running indefinitely passing -t
option:
docker run -dt --name tty-demo alpine
You can also pass an additional -it
called “Interactive mode” which enables the stdin opening without attachment. You can use this to interact mode to run shell commands to debug. Without using -t
the option is enough to keep the container running but in the end, you need to exec
fir commands.
Docker daemon will keep the process running as an interactive session, which means the main process Is still running waiting for user input, keeping the container running.
Let’s run the following command to list all Docker containers:
docker ps -a
You can check the following output:
As you can see, the container tail-demo
running.
3. Use the sleep infinity Command
This is the simplest method to prevent Docker containers from existing. In Linux sleep
commands pause the current execution based on a specific time.
Let’s see this in action. Run the following command:
docker run -d --name sleep-demo alpine sleep infinity
Using infinity
time can inform the system to sleep indefinitely, This will prevent the Docker container from shutting down, as the sleep process is active and running.
Let’s run the following command to list all Docker containers:
docker ps -a
You can check the following output:
As you can see, the container sleep-demo
running.
4. Use Infinite Loop Script
Same as the sleep infinity
command, you can run a similar script to keep Docker container running as the main process.
Run the following command:
docker run -d --name loop-demo alpine sh -c "while true; do sleep 1; done"
You can use a combination of while
and do
command to run the container indefinitely.
Let’s run the following command to list all Docker containers:
docker ps -a
You can check the following output:
As you can see, the container loop-demo
running.
5. Use Socket to Keep Container Running
You can run the Docker container using the Netcat utility. Running the nc
command with a specific port, start the socket that runs as the main process, and keep the container alive.
Run the following command:
docker run -d --name socket-demo alpine nc -l -p 3000
We can pass the nc
with additional options -l
and -p
with 3000 ports.
Let’s run the following command to list all Docker containers:
docker ps -a
You can check the following output:
As you can see, the container socket-demo
running.
6. Use cat Command
To keep Docker container running indefinitely, you can use cat
the command without passing any additional arguments. Passing cat
the command reads from stdin, since no arguments are passed it will wait indefinitely.
Run the following command:
docker run -dt --name cat-demo alpine cat
This simple hack keeps Docker container alive since the cat
process is still waiting.
Let’s run the following command to list all Docker containers:
docker ps -a
You can check the following output:
As you can see, the container cat-demo
running.
7. Leverage Background Process in Docker Container
Another effective way to keep Docker container running is to add a background process that keeps the container alive. This method is useful for running scripts batch jobs or scheduling tasks within the container.
Example Script
You can create the script called keep-alive.sh
#!/bin/bash
while true
do
echo "Container is running..."
sleep 60
done
Then, add this script to your Docker container setup:
# Dockerfile
FROM alpine
COPY keep-alive.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/keep-alive.sh
CMD ["/usr/local/bin/keep-alive.sh"]
When you run the Docker container with the above image it will keep the container running indefinitely, executing the keep-alive.sh
script, which outputs a message every 60 seconds.
This method is useful for maintaining long-running tasks that require optional output.
How to Keep Container Running in Kubernetes
Kubernetes run the container inside the pods. if the main container in a pod doesn’t have a long-running process or command, the container will exit.
1. Using a Deployment:
To prevent this, ensure that your container’s command keeps running. For example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: keep-container-running
spec:
replicas: 1
selector:
matchLabels:
app: keep-container-running
template:
metadata:
labels:
app: keep-container-running
spec:
containers:
- name: busybox
image: busybox
command: ["sh", "-c", "while true; do echo 'Running...'; sleep 3600; done"]
Here, the while true
loop ensures the container doesn’t exit immediately.
If your container’s default entrypoint
doesn’t have a command that keeps it running, you must override it with a custom command.
2. Liveness Probes for Monitoring:
To ensure the container stays healthy and keeps running, you can add a liveness probe to your pod spec YAML:
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
This probe checks if a specific command succeeds.
If it fails, Kubernetes will restart the container, helping maintain continuous operation.
Best Practices: Keep Docker Container Running
Keeping the Docker container running continuously can consume resources and affect system performance.
Here are some best practices to manage them effectively.
Using Supervisors to Manage Long-Running Processes
A supervisor program is useful for managing multiple running processes in a Linux environment, integrating it with your container can help manage the same but within the container.
Using the Supervisor with the container can be helpful if you want to manage more than one service inside the same container.
For example, Supervisor is a process control system for UNIX-like operating systems that can manage long-running processes within a Docker container:
Install Supervisor
# Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y supervisor
COPY supervisord.conf /etc/supervisor/conf.d/
CMD ["supervisord", "-c", "/etc/supervisor/supervisord.conf"]
Using the Supervisor gives you more control and better process management that is both easy to manage and monitor the process.
Even if you want to restart the process within the container you can manage without the risk of exiting the container as the main process superviord
is still running as PID1
This method is ideal for running more complex workloads inside a container.
Keep Docker Container Running Without Modifying Dockerfiles
Docker restart policies provide an alternative approach without the need to modify your current Dockerfile or any changes.
You can use flags like --restart unless-stopped
or --restart always
.
docker run --restart unless-stopped -d alpine tail -f /dev/null
The --restart unless-stopped
the flag will inform the Docker daemon to restart the container automatically in case of failure, making it an excellent option for production environments where uptime is critical.
Troubleshooting Common Issues with Persistent Containers
Even though we discussed many different methods to keep Docker container running, sometimes, despite using all these methods, the container may still stop unexpectedly.
Let’s discuss some helpful troubleshooting steps to identify the issue and fix it.
Diagnosing Docker Exits and Logs
The most common and easiest way to start the investigation is by checking the Docker logs. Using docker logs
is the straightforward way to investigate why a container has stopped.
Exit codes can also provide valuable information about the nature of the exit.
docker logs <container_id>
Exit codes:
By understanding these codes, you can identify and resolve issues more effectively.
I have written detailed article about “Avoid Docker Container Exit Code 137: Practical Solutions for Stable Containers“, be sure to checkout for investigation.
Optimizing Container Resources to Prevent Crashes
Docker containers are limited by default resource limits, so it’s essential to optimize your containers to prevent them from exceeding these limits.
Docker Container Default Memory Limit: You Should Know!
Set Memory and CPU Limits
docker run -m 512m --cpus="1.0" alpine
This example limits the container to 512MB of memory and 1 CPU core, helping prevent crashes due to resource overuse.
Recommended reading: Avoid Docker Container Exit Code 137: Practical Solutions for Stable Containers
Conclusion
In this blog, we understand that debugging a Docker container can be troublesome due to how it manages the Docker lifecycle. Initially understand what happens when you run a Docker container and the reason why Docker containers exit immediately after starting.
Whether using the bash shell, command like tail -f /dev/null, or sleep infinity all these methods essentially serve the same purpose enabling the developer to keep Docker container running for debugging purposes.
Choose the one that is more suitable based on your requirements.
Do you want to learn about the Docker container security?
Checkout the best practice for Docker Container Security Cheatsheet: Don’t Get Hacked🔐
FREE EBook – Docker Defence Unbeatable Security
Are you leveraging Docker’s potential, but worried about security vulnerabilities? Our ebook, “Docker Defence: Unbeatable Security“, is your key to mastering container security. Packed with actionable checklists and expert tips, you’ll discover:
Don’t wait! Download your free copy and unlock the full potential of Docker!