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 running 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).
However, as noted by bviktor in the comments:
Overriding entrypoint will mess up with your Dockerfile if it has anything specified.
systemd
is of particular interest.
Tailing /dev/null
also doesn't sound very convincing: in essence you bombard your system with completely unnecessary system calls.
The other solution with sleep looks much better.
That relies on sleep infinity
, a GNU coreutils extension not contemplated in POSIX.