Nan Xiao Nan Xiao - 25 days ago 12
Linux Question

Why does "docker attach" hang?

I can run an

ubuntu
container successfully:

# docker run -it -d ubuntu
3aef6e642327ce7d19c7381eb145f3ad10291f1f2393af16a6327ee78d7c60bb
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3aef6e642327 ubuntu "/bin/bash" 3 seconds ago Up 2 seconds condescending_sammet


But executing
docker attach
hangs:

# docker attach 3aef6e642327


Until I press any key, such as
Enter
:

# docker attach 3aef6e642327
root@3aef6e642327:/#
root@3aef6e642327:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var


Why does
docker attach
hang?

Update:

After reading the comments, I think I get the answers:

prerequisite:

"docker attach" reuse the same tty, not open new tty.

(1) Executing the
docker run
without daemon mode:

# docker run -it ubuntu
root@eb3c9d86d7a2:/#


Everything is OK, then run
ls
command:

root@eb3c9d86d7a2:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@eb3c9d86d7a2:/#


(2) Run
docker run
in daemon mode:

# docker run -it -d ubuntu
91262536f7c9a3060641448120bda7af5ca812b0beb8f3c9fe72811a61db07fc


Actually, the following should have been outputted to stdout from the running container:

root@91262536f7c9:/#


So executing
docker attach
seems to hang, but actually it is waiting for your input:

# docker attach 91262536f7c9
ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@91262536f7c9:/#

Answer

It does not really hang. As you can see in the comment below (You are running "/bin/bash" as command) it seems to be expected behaviour when attaching.

As far as I understand you attach to the running shell and just the stdin/stdout/stderr - depending on the options you pass along with the run command - will just show you whatever goes in/out from that moment. (Someone with a bit more in-depth knowledge hopefuly can explain this on a higher level).

As I wrote in my comment on your question, there are several people who have opened an issue on the docker github repo describing similar behaviour:

Since you mention shell, I assume you have a shell already running. attach doesn't start a new process, so what is the expected behavior of connecting to the in/out/err streams of a running process? I didn't think about this. Of course this is the expected behavior of attaching to a running shell, but is it desirable?

Would it be at all possible to flush stdout/stderr on docker attach thereby forcing the shell prompt to be printed or is it a bit more complex than that? That's what I personally would "expect" when attaching to an already running shell.

Feel free to close this issue if necessary, I just felt the need to document this and get some feedback.

  • Taken from a comment on this github issue. You can find more insight in the comments of this issue.

If instead of enter you would start typing a command, you would not see the extra empty prompt line. If you were to run

$ docker exec -it ubuntu bash <container-ID-or-name>

where <container-ID-or-name> is the ID or name of the container after you run docker run -it -d ubuntu (so 3aef6e642327 or condescending_sammet in your question) it would run a new command, thus not having this "stdout problem" of attaching to an existing one.

Example

If you would have a Dockerfile in a directory containing:

FROM ubuntu:latest
ADD ./script.sh /timescript.sh 
RUN chmod +x /timescript.sh
CMD ["/timescript.sh"]

And have a simple bash script script.sh in the same directory containing:

#!/bin/bash

#trap ctrl-c and exit, couldn't get out
#of the docker container once attached
trap ctrl_c INT
function ctrl_c() {
    exit
}

while true; do
    time=$(date +%N)
    echo $time;
    sleep  1;
done

Then build (in this example in the same directory as the Dockerfile and script.sh) and run it with

$ docker build -t nan-xiao/time-test .
..stuff happening...
$ docker run -itd --name time-test nan-xiao/time-test

Finally attach

$ docker attach time-test

You will end up attached to a container printing out the time every second. (CTRL-C to get out)

Example 2

Or if you would have a Dockerfile containing for example the following:

FROM ubuntu:latest
RUN apt-get -y install irssi
ENTRYPOINT ["irssi"]

Then run in the same directory:

$ docker build -t nan-xiao/irssi-test .

Then run it:

$ docker run -itd --name irssi-test nan-xiao/irssi-test

And finally

$ docker attach irssi-test

You would end up in a running irssi window without this particular behaviour. Of course you can substitute irrsi for another program.

Comments