docker run a shell script in the background without exiting the container
You haven't explained why you want to see your container running after your script has exited, or whether or not you expect your script to exit.
A docker container exits as soon as the container's CMD
exits. If you want your container to continue running, you will need a process that will keep running. One option is simply to put a while loop at the end of your script:
while :; do
sleep 300
done
Your script will never exit so your container will keep running. If your container hosts a network service (a web server, a database server, etc), then this is typically the process the runs for the life of the container.
If instead your script is exiting unexpectedly, you will probably need to take a look at your container logs (docker logs <container>
) and possibly add some debugging to your script.
If you are simply asking, "how do I run a container in the background?", then Emil's answer (pass the -d
flag to docker run
) will help you out.
Docker container will automatically stop after docker run -d
The centos dockerfile has a default command bash
.
That means, when run in background (-d
), the shell exits immediately.
Update 2017
More recent versions of docker authorize to run a container both in detached mode and in foreground mode (-t
, -i
or -it
)
In that case, you don't need any additional command and this is enough:
docker run -t -d centos
The bash will wait in the background.
That was initially reported in kalyani-chaudhari's answer and detailed in jersey bean's answer.
vonc@voncvb:~$ d ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4a50fd9e9189 centos "/bin/bash" 8 seconds ago Up 2 seconds wonderful_wright
Note that for alpine, Marinos An reports in the comments:
docker run -t -d alpine/git
does not keep the process up.
Had to do:docker run --entrypoint "/bin/sh" -it alpine/git
Original answer (2015)
As mentioned in this article:
Instead of running with
docker run -i -t image your-command
, using-d
is recommended because you can run your container with just one command and you don’t need to detach terminal of container by hitting Ctrl + P + Q.
However, there is a problem with
-d
option. Your container immediately stops unless the commands keep running in foreground.
Docker requires your command to keep running in the foreground. Otherwise, it thinks that your applications stops and shutdown the container.
The problem is that some application does not run in the foreground. How can we make it easier?
In this situation, you can add
tail -f /dev/null
to your command.
By doing this, even if your main command runs in the background, your container doesn’t stop because tail is keep running in the foreground.
So this would work:
docker run -d centos tail -f /dev/null
Or in Dockerfile:
ENTRYPOINT ["tail"]
CMD ["-f","/dev/null"]
A docker ps
would show the centos container still running.
From there, you can attach to it or detach from it (or docker exec
some commands).
Correct way to detach from a container without stopping it
Update: As mentioned in below answers Ctrl+p, Ctrl+q will now turn interactive mode into daemon mode.
Well Ctrl+C (or Ctrl+\) should detach you from the container but it will kill the container because your main process is a bash.
A little lesson about docker.
The container is not a real full functional OS. When you run a container the process you launch take the PID 1 and assume init power. So when that process is terminated the daemon stop the container until a new process is launched (via docker start) (More explanation on the matter http://phusion.github.io/baseimage-docker/#intro)
If you want a container that run in detached mode all the time, i suggest you use
docker run -d foo
With an ssh server on the container. (easiest way is to follow the dockerizing openssh tutorial https://docs.docker.com/engine/examples/running_ssh_service/)
Or you can just relaunch your container via
docker start foo
(it will be detached by default)
Docker CMD run bash script in background inside container
As I mentioned in my comment, you should be able to run your function in the background from within start.sh
. if you don't call wait
, then the container will exit (with the exit code of the foreground process) at the end of the script. If you do wait for the background function, you should see both statements printed to the container log before it completes.
It's usually best practice to have around one process per container, but definitely possible to have more, and there are good cases for applying that approach.
How to create a Dockerfile so that container can run without an immediate exit
Let's clear things out.
In general, a container exits as soon as its entrypoint is successfully executed.
In your case, without being a python expert this ENTRYPOINT [ "flask", "run", "--host", "0.0.0.0:5000" ]
would be enough to keep the container alive. But I guess you have some configuration error and due to that error the container exited before running flask
command. You can validate this by running docker ps -a
and inspect the exit code(possibly 1).
Let's now discuss about the questions in your edits.
The key part of your misunderstanding derives from the -d
flag.
You are right to think that setting bash
as entrypoint would be enough to keep container alive but you need to attach to that shell.
When running in detach mode(-d
), container will execute bash
command but as soon as no one is attached to that shell, it will exit. In addition, using this flag will prevent you from viewing container logs lively(however you may use docker logs container_id
to debug) which is very useful when you are in an early phase of setting thing up. So I recommend using this flag only when you are sure that everything works as intended.
To attach to bash shell and keep container alive, you should use the -it
flag so that the bash shell will be attached to the current shell invoking the docker run
command.
-t : Allocate a pseudo-tty
-i : Keep STDIN open even if not attached
Please also consult official documentation about foreground vs background mode.
Related Topics
Writing a Syscall to Count Context Switches of a Process
Are System Calls on Windows Inherently Slower Than Linux
Watermarking Video from The Linux Command Line
How to Touch a File and Mkdir If Needed in One Line
Test If String Has Non Whitespace Characters in Bash
How to Let Users Run a Script with Root Permissions
Fork() and Stdout/Stderr to The Console from Child Processes
Calculate Total Disk I/O by a Single Process
Find The Depth of The Current Path
How to Do a While Loop with a String Redirected into It
Does I2C Driver Need to Be Implemented Just Like Any Other Character Device Driver
How to Remount The /Proc Filesystem in a Docker as a R/W System
What Does an Asterisk at The End of a Mv Command Do
Live Socket Monitoring with Netlink Inet_Diag
How to Get The Percent of Packets Received from Ping in Bash