Trying to understand the relation of tty between the host and container when the docker run command is executed

Hello Friends

If is executed the following command

docker run --name ubuntu-it -it ubuntu

The container named ubuntu-it, based on the ubuntu image, is created, run, is offered a tty and finally remains running. It can be stopped with the exit command. Here the importance about the it option to have a shell available for human interaction. It to have available the features about the STDIN and STDOUT/STDERR streams within the current running container through the shell within the tty.

For experimental purposes, if is executed the following commands

docker run --name ubuntu-a ubuntu ls
docker run --name ubuntu-b ubuntu date

The containers named ubuntu-a and ubuntu-b, based on the ubuntu image, are created, run, are listed/displayed the execution of the ls and date commands and finally the containers are stopped.

The ls and date commands are executed within the running containers prior to be stopped.

Question

If the it option was not used for each docker run command.

  • Why in the host’s tty is possible see the listed/displayed data of the ls and date commands?

Observation: I have this consult because when I use the docker start command, to see the displayed data of the ls/date command according the case is mandatory use the a option, and if I use the ai option it is same as to use the it option of the docker run command from the beginning

1 Like

My old reply in another topic could be useful here:

In your case, the TTY is not for having an output. Some programs like a shell need a pseudo TTY to be able to run. You run the following command:

docker run -d --name bash-1 bash

It will run and stop immediately. Now run this:

docker run -d --name bash-2 -t bash

It will keep running. Or just try to run it in interactive mode:

docker run --rm -i bash

You can type characters, but there is nothing to handle what you typed without the TTY.

Or you can run this:

echo 'hello' | docker run --rm -i bash cat

You still don’t have TTY, but you don’t need because the content is sent to the standard input and cat reads that, not what you type.

That is why we often use -it together because most of the time we just want to get a shel in the container which requires both. Having an interactive mode and also a TTY. Using only -t kept the container alive, but it was useful only because it ran in the background in detached mode. If you try it in the foreground (attached mode), you will get a bash shell, but when you type “exit” it will not exit and press enter, it will not exit. And when you try to run “read test” in the shell, it will do nothing and you won’t get the prompt back by pressing enter, only by pressing CTRL+C.

docker run --name mustbekilled -t bash

So you will need another terminal and run:

docker rm -f mustbekilled

And when you run only:

docker run --name noprompt -i bash

You will get no prompt in the shell, but you can type commands, but the read command will not work either. Fortunately the exit command will work in this mode.

2 Likes

Thanks for the reply

Yes. To get a container running, based on Linux, at foreground I use the it option for the docker run command. Of course it keeps the container running. A way to exit and keep the container running is do a detach ^P^Q.

For a container running, based on Linux, at background. It was executed from the beginning through docker run -itd ubuntu - If I enter to that container through the docker attach and is executed the ping spring.io command, it does its job as expected and two points to consider:

  1. is displayed the command’s output within the running container itself through its own internal tty
  2. is possible see the displayed data of the command because at point I am attached to the internal tty of the container through the tty of the host.

It is practically the same scenario for the docker exec command. Therefore I can work through the I/O Streams because I am working within the running container and thus using its own internal tty.

But it is not clear for me. The same scenario yet. Again the two commands:

docker run --name ubuntu-x ubuntu ls
docker run --name ubuntu-y ubuntu date

I expected the following for each command:

  1. creation of the container
  2. start of the container
  3. Execution of the command within the running container and see nothing in the host’s tty because the command was executed within the container itself and the host’s tty is not attached to the internal tty of the container
  4. the container is stopped

The point 3 is my doubt because was possible see the command’s output in the host’s tty.

I expected “something” like this about the “correct scenario”:

docker run --name -a ubuntu-x ubuntu ls
docker run --name -a ubuntu-y ubuntu date

Observe the a option to indicate to do an attach. Of course really the a option does more.

-a, --attach Attach to STDIN, STDOUT or STDERR

Therefore with that a option now should happen the following:

  1. creation of the container
  2. start of the container
  3. Execution of the command within the running container and see its output in the host’s tty because the command was executed within the container itself and the host’s tty is attached to the internal tty of the container
  4. the container is stopped

Therefore I am considering two tty as follows:

  1. The internal tty of the running container. My point is, any command is executed in a shell, and it through a tty.
  2. The tty of the host that would be attached (or executed) or not with the tty of the container

Thanks for your understanding.

Forget about the TTY. I tried to explain what it is for, but there is no TTY in the container unless you ask for it. There is a process and a process has a standard output, standard error and a standard input stream.You are atacching to that, not a TTY.

The option -a or --attach is there for you to specify which stream you want to attach. Not using that option means all of the streams while -d or --detach means none of the streams whether you get an output or not has nothing to do with TTY


Thanks again for the polite reply

Sorry for the confusion about tty. Yes, I am agree, there is only one tty, the host. And the container does not have an own internal tty.

But it has the 3 standards I/O Streams. In general for any tty/shell:

STDIN:  to input commands
STDOUT: to output data (i.e: result of a command)
STDERR: to output errors

Now, When the docker run it command is executed it creates and run the container as expected and brings the Interactive Terminal to use mostly the STDIN and STDOUT streams, it to write (IN) and get results (OUT) through a tty.

I am assuming STDERR is available too for the scenario if an incorrect command is provided. Then appears the error message.

But see the following about the i and t options

-i, --interactive Keep STDIN open even if not attached

-t, --tty Allocate a pseudo-TTY

From above, is clear i is about the STDIN stream because it is indicated explicitly, but from what option the STDOUT is available? I would assume by simple discard it comes from t. I hope see my point. Same question about STDERR. Anyway, we got an interaction with all the I/O Streams of the container through the tty.

-a, --attach Attach to STDIN, STDOUT or STDERR

Brings the 3 I/O streams together. But a first glance it seems as an equivalence of it but according with the current documentation examples it has other purposes about customization. It in the Attach to STDIN/STDOUT/STDERR (-a, --attach) section

Even more confuse the first code available in the link

docker run -a stdin -a stdout -i -t ubuntu /bin/bash

What extra feature does the a option offer against it? I hope you see my point. The it option already brings the 3 I/O Streams. It is other reason of confusion.

Forget about the TTY. I tried to explain what it is for, but there is no TTY in the container unless you ask for it

Agree, it comes through the t option

There is a process and a process has a standard output, standard error and a standard input stream.You are atacching to that, not a TTY.

Absolutely agree, again sorry for the confusion.

The option -a or --attach is there for you to specify which stream you want to attach

Same consideration about docker run -a stdin -a stdout -i -t ubuntu /bin/bash What extra feature does the a option offer against it?

Not using that option means all of the streams

But using it instead, right?

while -d or --detach means none of the streams

And even itd for Linux containers. Agree, because the container runs at background. The tty of the host has no access to the I/O Streams of the container. Am I correct?

But 
 therefore again about:

docker run --name ubuntu-y ubuntu date

Why the STDOUT of the running container - I mean the date - appears in the tty?

Thanks for your understanding.

Please, read my replies more carefully and multiple times if needed. Also try the commands I shared which includes checking the metadata of the container. I could only repeat myself and I don’t think that would lead us anywhere. I wrote about what happens when you don’t use -a and what happens when you do. I also wrote about how the tty has nothing to do with the standard streams, you “agreed”, yet you seem to ask the same question again. Of course the output of the date command appears as you didn’t disable the standard output by using -a and the default behavior is attaching to all the streams.

You probably have an expectation.

Update:
I incorrectly wrote docker run would attach to all the streams without using -a. It would attach to stdout and stderrr.