425

I run a container in the background using

 docker run -d --name hadoop h_Service

it exits quickly. But if I run in the foreground, it works fine. I checked logs using

docker logs hadoop

there was no error. Any ideas?

DOCKERFILE

 FROM java_ubuntu_new
 RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
 RUN dpkg -i cdh4-repository_1.0_all.deb
 RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
 RUN  apt-get update
 RUN apt-get install -y hadoop-0.20-conf-pseudo
 RUN dpkg -L hadoop-0.20-conf-pseudo
 USER hdfs
 RUN hdfs namenode -format
 USER root
 RUN apt-get install -y sudo
 ADD . /usr/local/
 RUN chmod 777 /usr/local/start-all.sh
 CMD ["/usr/local/start-all.sh"]

start-all.sh

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start
 /etc/init.d/hadoop-hdfs-datanode start
 /etc/init.d/hadoop-hdfs-secondarynamenode start
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start
 /bin/bash
Vini.g.fer
  • 11,639
  • 16
  • 61
  • 90
Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • 4
    The golden rule is that you should prevent your dockerized servers from daemonizing. Most server packages have options to force them in the foreground since daemonizing is the normal case. – Arnaud Meuret Sep 22 '15 at 10:29
  • 8
    Whatever you are hoping to accomplish, **`chmod 777` is *insecure* and *wrong.*** You should revert to sane permissions (probably 755 in this case). – tripleee Dec 03 '19 at 05:57

19 Answers19

377

This did the trick for me:

docker run -dit ubuntu

After it, I checked for the processes running using:

docker ps -a

For attaching again the container

docker attach CONTAINER_NAME

TIP: For exiting without stopping the container type: ^P^Q

camposer
  • 5,152
  • 2
  • 17
  • 15
  • what does `dit` do? I thought `i` was interactive..? – Tommy Feb 01 '16 at 19:16
  • 34
    @Tommy, from https://docs.docker.com/engine/reference/commandline/run/ -d, --detach Detached mode: run command in the background, -i, --interactive Keep STDIN open even if not attached, -t, --tty Allocate a pseudo-TTY `-dit` is just shorthand –  Mar 22 '16 at 18:07
  • 5
    @am17torres right, sorry let me clarify my confusing question; d is detached and i is interactive, so the combination of d and i is confusing to me. I thought d was to launch it as a background (non-interactive) process. – Tommy Mar 22 '16 at 19:59
  • 3
    @Tommy When these options combined, container will **enter interactive mode in background**. – YON Apr 12 '16 at 01:39
  • 3
    @Tommy, @am17torres `-di` is the minimum required, the `-t` option is redundant when used with `-d` if I understand correctly – Renaud May 30 '16 at 13:16
  • 2
    Actually you won't be able to see your prompt if you reattach without `-t` enabled... but since I usually `exec` a new bash every time I don't notice. I've had problems detaching from a mac but perhaps I'm doing this wrong.. – Renaud May 30 '16 at 13:19
  • 2
    I guess I don't know what the phrase "interactive mode in background" means or that it is confusing. – Tommy May 31 '16 at 12:32
  • If you had to do `docker ps -a` to see it, it did not work for you. That command shows ALL existing containers, including the ones that are NOT running. The command `docker ps` alone is the correct command to see running containers – jucardi Nov 25 '16 at 00:10
  • 2
    This won't help if main process will exit immediately – Neftanic Mar 06 '17 at 18:13
  • Extremely helpful TIP I would say. I was struggling to find how to close the container without exiting it and I did it successfully using your tip of using ^P^Q (read escape sequence). Thanks. – Ayushi Agarwal Sep 04 '18 at 11:00
  • how to keep it running if I already created the container before without "-dit" ? – neobie May 01 '20 at 16:32
  • 1
    When I tried to attach it, it immidiately throws me this error `You cannot attach to a stopped container, start it first`. – arahpanah Mar 17 '22 at 02:49
207

A docker container exits when its main process finishes.

In this case it will exit when your start-all.sh script ends. I don't know enough about hadoop to tell you how to do it in this case, but you need to either leave something running in the foreground or use a process manager such as runit or supervisord to run the processes.

I think you must be mistaken about it working if you don't specify -d; it should have exactly the same effect. I suspect you launched it with a slightly different command or using -it which will change things.

A simple solution may be to add something like:

while true; do sleep 1000; done

to the end of the script. I don't like this however, as the script should really be monitoring the processes it kicked off.

(I should say I stole that code from https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh)

Adrian Mouat
  • 44,585
  • 16
  • 110
  • 102
91

I would like to extend or dare I say, improve answer mentioned by camposer

When you run

docker run -dit ubuntu

you are basically running the container in background in interactive mode.

When you attach and exit the container by CTRL+D (most common way to do it), you stop the container because you just killed the main process which you started your container with the above command.

Making advantage of an already running container, I would just fork another process of bash and get a pseudo TTY by running:

docker exec -it <container ID> /bin/bash
Community
  • 1
  • 1
Krishna Gupta
  • 1,219
  • 11
  • 12
76

Why docker container exits immediately?

If you want to force the image to hang around (in order to debug something or examine state of the file system) you can override the entry point to change it to a shell:

docker run -it --entrypoint=/bin/bash myimagename
RJFalconer
  • 10,890
  • 5
  • 51
  • 66
49

whenever I want a container to stay up after finish the script execution I add

&& tail -f /dev/null

at the end of command. So it should be:

/usr/local/start-all.sh && tail -f /dev/null
Thiago Ramos
  • 649
  • 8
  • 6
  • 3
    This could solve, but I wonder whether this command will cause memory leak or other problem? How is it compared with running `while true; do sleep 1; done;`? – Flying onion Jul 03 '20 at 10:03
30

If you need to just have a container running without exiting, just run

docker run -dit --name MY_CONTAINER MY_IMAGE:latest

and then

docker exec -it MY_CONTAINER /bin/bash

and you will be in the bash shell of the container, and it should not exit.

The following worked only with roslaunch in a ROS simulation, this is most likely not a default parameter for docker-compose!

Mind: This is hard to read, and it seems to be only about a self-written parameter. Just skip it.

Or if the exit happens during docker-compose, use

command: bash -c "MY_COMMAND --wait"

as already stated by two other answers here (though not that clearly referring to docker-compose, that is why I still mention the "wait" trick again).

In the ROS simulation, it would be, for example:

command: bash -c "roslaunch gazebo_ros empty_world.launch --wait"

Using --wait was the core to get a so-called ROS network on docker-compose to work, see example code at ROS in docker-compose leads to "bash: line 0: cd: MYPROJECT: No such file or directory". More on roslaunch is at Docker on WSL2: Dockerfile: how to test whether ROS gazebo can connect to already working X server (using its X11 display on Windows)?.

Thus, this --wait must have been an argument for a command like roslaunch gazebo_ros empty_world.launch. But when checking the linked tutorial Tutorial: Using roslaunch to start Gazebo, world files and URDF models, there is no such parameter in the code, just:

roslaunch gazebo_ros empty_world.launch paused:=true use_sim_time:=false gui:=true throttled:=false recording:=false debug:=true verbose:=true gui_required:=true

That is why I guess that it must have been a self-written extension of the given parameters of the project.

I tried this --wait later again in other settings, did not work. In the ROS launch script, where it worked, it likely just shadowed the workaround of another answer in this Q/A (&& tail ...).

questionto42
  • 7,175
  • 4
  • 57
  • 90
  • Could you elaborate on what you mean by 'MY_COMMAND' here? Do you mean one should write one's own bash script with a --wait option? What would such a script look like? – Delon Mar 19 '22 at 09:23
  • @Delon For example, if you run a python file: `command: bash -c "python main.py --wait"`. You can put anything you would want to run in the terminal of the container there. No script needed, just *possible as well* as anything else you could run in the bash. – questionto42 Mar 22 '22 at 17:30
  • Maybe a useful command: `docker run -d -p 8888:8888 -it --name indexing_8 -v /mount/xyz:/mount/xyz -v /pylucene-docker:/code coady/pylucene:8` – PinkBanter Nov 29 '22 at 09:57
  • I don't this works anymore it's 2023 – user1034912 Mar 08 '23 at 03:31
  • @user1034912 Do you mean the `--wait` trick? I checked it now where I got it from. It is most likely a self-written extension of parameters for a ROS simulation. – questionto42 Mar 08 '23 at 22:18
26

Add this to the end of Dockerfile:

CMD tail -f /dev/null

Sample Docker file:

FROM ubuntu:16.04

# other commands

CMD tail -f /dev/null

Reference

Kert Kukk
  • 666
  • 1
  • 10
  • 20
23

A nice approach would be to start up your processes and services running them in the background and use the wait [n ...] command at the end of your script. In bash, the wait command forces the current process to:

Wait for each specified process and return its termination status. If n is not given, all currently active child processes are waited for, and the return status is zero.

I got this idea from Sébastien Pujadas' start script for his elk build.

Taking from the original question, your start-all.sh would look something like this...

 #!/usr/bin/env bash
 /etc/init.d/hadoop-hdfs-namenode start &
 /etc/init.d/hadoop-hdfs-datanode start &
 /etc/init.d/hadoop-hdfs-secondarynamenode start &
 /etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
 sudo -u hdfs hadoop fs -chmod 777 /
 /etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
 wait
Brian Olsen
  • 935
  • 6
  • 17
  • This did the trick also in docker-compose with the same issue, using `--wait`. – questionto42 Apr 25 '21 at 10:34
  • The `wait` command is different from a possible`--wait` option which is not a standard option for most commands. – tripleee Aug 20 '21 at 06:31
  • Can you clarify which command has the --wait option? I am using docker-compose but neither my image, not the compose file has any command or entrypoint. We prefer starting the container without any entrypoint, and then separately bringup our services (not automatically as part of container up). But apparently with compose, command or entrypoint is mandatory. Trying to understand what this --wait is. – anuragz Dec 31 '21 at 03:24
17

You need to run it with -d flag to leave it running as daemon in the background.

docker run -d -it ubuntu bash

Vivek
  • 657
  • 11
  • 14
6

My pracitce is in the Dockerfile start a shell which will not exit immediately CMD [ "sh", "-c", "service ssh start; bash"], then run docker run -dit image_name. This way the (ssh) service and container is up running.

Leon
  • 3,124
  • 31
  • 36
2

Adding

exec "$@"

at the end of my shell script was my fix!

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
Adam k
  • 29
  • 1
2

I added read shell statement at the end. This keeps the main process of the container - startup shell script - running.

Jaydeep Ranipa
  • 421
  • 5
  • 16
1

Coming from duplicates, I don't see any answer here which addresses the very common antipattern of running your main workload as a background job, and then wondering why Docker exits.

In simple terms, if you have

my-main-thing &

then either take out the & to run the job in the foreground, or add

wait

at the end of the script to make it wait for all background jobs.

It will then still exit if the main workload exits, so maybe run this in a while true loop to force it to restart forever:

while true; do
    my-main-thing &
    other things which need to happen while the main workload runs in the background
    maybe if you have such things
    wait
done

(Notice also how to write while true. It's common to see silly things like while [ true ] or while [ 1 ] which coincidentally happen to work, but don't mean what the author probably imagined they ought to mean.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Adding --wait is mentioned by @BrianOlsen 2017. Still a good answer. – questionto42 Aug 19 '21 at 22:31
  • If you have a command which supports an option with that name, it will certainly be useful; but it does not extend to scenarios where you don't have that option. It's not clear to me if the answer was supposed to suggest just `wait` without the dashes but if so, this should hopefully at least work as a clarification. – tripleee Dec 30 '21 at 13:29
  • 1
    You are right, you got my upvote anyway. Your answer is not a duplicate, it shows the direct way of using `wait`. Your answer makes it clearer why waiting solves the exiting problem: stay awake for all background jobs. – questionto42 Dec 30 '21 at 19:19
  • 1
    Thanks for getting back to me with a clarification, much appreciated. – tripleee Dec 30 '21 at 19:50
0

There are many possible ways to cause a docker to exit immediately. For me, it was the problem with my Dockerfile. There was a bug in that file. I had ENTRYPOINT ["dotnet", "M4Movie_Api.dll] instead of ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]. As you can see I had missed one quotation(") at the end.

To analyze the problem I started my container and quickly attached my container so that I could see what was the exact problem.

C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b


C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b

Where 4ea373efa21b is my container id. This drives me to the actual issue.

enter image description here

After finding the issue, I had to build, restore, publish my container again.

Sibeesh Venu
  • 18,755
  • 12
  • 103
  • 140
0

If you check Dockerfile from containers, for example fballiano/magento2-apache-php

you'll see that at the end of his file he adds the following command: while true; do sleep 1; done

Now, what I recommend, is that you do this

docker container ls --all | grep 127

Then, you will see if your docker image had an error, if it exits with 0, then it probably needs one of these commands that will sleep forever.

RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
0

Docker container terminates immediately when it did not have any foreground process that helps to connect to user terminal. For example, there is no web server up running in that container.

There are couple of ways to create a foreground process. One such method is to redirect to /dev/null which prevents container from immediate exit. After that you can use exec command with -it parameter to attach it to your terminal.

docker run -d ubuntu tail -f /dev/null
docker exec -it 0ab99d8ab11c /bin/bash
kta
  • 19,412
  • 7
  • 65
  • 47
0

$ docker run -di image

It works.

Richi RM
  • 829
  • 3
  • 11
0

docker logs information is not usually helpful to me. Sometimes app's log is same as docker logs output, sometimes is not.

docker inspect not helpful in most case either, unless it is a very obvious error.

If your Entrypoint or last command failed, just find the log generated by that command. Persist the container log through a volume on your host and check the log.

Alternatively, if you prefer a somehow interactive environment. Let you container enter sleep mode. Entrypoint sleep(whatever long you like), then log into the container with docker exec -it container_id sh and run your Entrypoint command manually, see what is going on.

ychz
  • 533
  • 2
  • 7
  • 15
-8

Since the image is a linux, one thing to check is to make sure any shell scripts used in the container have unix line endings. If they have a ^M at the end then they are windows line endings. One way to fix them is with dos2unix on /usr/local/start-all.sh to convert them from windows to unix. Running the docker in interactive mode can help figure out other problems. You could have a file name typo or something. see https://en.wikipedia.org/wiki/Newline

dskow
  • 924
  • 6
  • 9