dockerdevopsdocker-containerdocker-imagedocker-run

Docker container will automatically stop after "docker run -d"


According to tutorial I read so far, use "docker run -d" will start a container from image, and the container will run in background. This is how it looks like, we can see we already have container id.

root@docker:/home/root# docker run -d centos
605e3928cdddb844526bab691af51d0c9262e0a1fc3d41de3f59be1a58e1bd1d

But if I ran "docker ps", nothing was returned.

So I tried "docker ps -a", I can see container already exited:

root@docker:/home/root# docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                         PORTS               NAMES
605e3928cddd        centos:latest         "/bin/bash"         31 minutes ago      Exited (0) 31 minutes ago                          kickass_swartz

Anything I did wrong? How can I troubleshoot this issue?


Solution

  • 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.