Confused about Docker -t option to Allocate a pseudo-TTY
The -t
option goes to how Unix/Linux handles terminal access. In the past, a terminal was a hardline connection, later a modem based connection. These had physical device drivers (they were real pieces of equipment). Once generalized networks came into use, a pseudo-terminal driver was developed. This is because it creates a separation between understanding what terminal capabilities can be used without the need to write it into your program directly (read man pages on stty
, curses
).
So, with that as background, run a container with no options and by default you have a stdout stream (so docker run | <cmd>
works); run with -i
, and you get stdin stream added (so <cmd> | docker run -i
works); use -t
, usually in the combination -it
and you have a terminal driver added, which if you are interacting with the process is likely what you want. It basically makes the container start look like a terminal connection session.
docker run with --interactive and --tty flag
There are two ways in which you can interact with a running container
- attach
- exec
--interactive flag
As you mentioned it already says
Keep STDIN open even if not attached
Which from my understanding means it will read inputs from your terminal/console and reacts or present output to it. If you run docker run --tty alpine /bin/sh
and docker run --tty --interactive alpine /bin/sh
. One with --interactive
will react to it.
attach
Attach to a running process
If the docker container was started using /bin/bash
command, you can access it using attach, if not then you need to execute the command to create a bash instance inside the container using exec
.
More in depth: If docker container is started using /bin/bash
then it becomes containers PID 1 and attach
command will attach you to PID 1.
exec
Creates new process
If you want to create a new process inside container than exec it used like exec
is used to execute apt-get
command inside container without attaching to it or run a node or python script.
Eg: docker exec -it django-prod python migrate
See here -i
is for interactive and -t
is for --tty
that is pseudo-TTY. Interactive so that you can enter if something is prompted by this command.
What does it mean to attach a tty/std-in-out to dockers or lxc?
stdin, stdout, and ttys
are related concepts. stdin
and stdout
are the input and output streams of a process. A pseudo terminal (also known as a tty
or a pts
) connects a user's "terminal" with the stdin
and stdout
stream, commonly (but not necessarily) through a shell such as bash
. I use quotes around "terminal" since we really don't use a terminal in the same sense today.
In the case of docker, you'll often use -t
and -i
together when you run processes in interactive mode, such as when starting a bash
shell. In the case of the shell you want to be able to issue commands and read the output.
The code docker uses to attach stdout/stdin
has all the dirty details.
Error The input device is not a TTY
Remove the -it
from your cli to make it non interactive and remove the TTY. If you don't need either, e.g. running your command inside of a Jenkins or cron script, you should do this.
Or you can change it to -i
if you have input piped into the docker command that doesn't come from a TTY. If you have something like xyz | docker ...
or docker ... <input
in your command line, do this.
Or you can change it to -t
if you want TTY support but don't have it available on the input device. Do this for apps that check for a TTY to enable color formatting of the output in your logs, or for when you later attach to the container with a proper terminal.
Or if you need an interactive terminal and aren't running in a terminal on Linux or MacOS, use a different command line interface. PowerShell is reported to include this support on Windows.
What is a TTY? It's a terminal interface that supports escape sequences, moving the cursor around, etc, that comes from the old days of dumb terminals attached to mainframes. Today it is provided by the Linux command terminals and ssh interfaces. See the wikipedia article for more details.
To see the difference of running a container with and without a TTY, run a container without one: docker run --rm -i ubuntu bash
. From inside that container, install vim with apt-get update; apt-get install vim
. Note the lack of a prompt. When running vim against a file, try to move the cursor around within the file.
Could you clarify when -it should be used in a docker run command?
Mentioning the docs,
For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process.
Essentially what that does is adding a terminal driver which allows you to interact with your container as a terminal session.
After running your container, you can run docker ps
to get the hash id of your container which you can then access by running:
docker exec -it containeridhash sh
Docker command fails during build, but succeeds while executed within running container
The pwd is not persistent across RUN commands. You need to cd and configure within the same RUN.
This Dockerfile works fine:
FROM ubuntu:12.10
RUN apt-get update
RUN apt-get -y install libpcre3 libssl-dev
RUN apt-get -y install libpcre3-dev
RUN apt-get -y install wget zip gcc
RUN wget http://nginx.org/download/nginx-1.4.1.tar.gz
RUN gunzip nginx-1.4.1.tar.gz
RUN tar -xf nginx-1.4.1.tar
RUN wget --no-check-certificate https://github.com/max-l/nginx_accept_language_module/archive/master.zip
RUN unzip master
RUN cd nginx-1.4.1 && ./configure --add-module=../nginx_accept_language_module-master --with-http_ssl_module --with-pcre=/lib/x86_64-linux-gnu --with-openssl=/usr/lib/x86_64-linux-gnu
Related Topics
"Thread Apply All Bt Full" Gives Blank in Gdb
How to Cross Compile R Packages for MACos from a Linux Environment
How to Count Most Occuring Sequence of 3 Letters Within a Word with a Bash Script
Erge Text Files Ordered by Numerical Filenames in Bash
Is Assembler Portable Between Linux Distros
Selenium Doesn't Refresh Page on Jenkins
Sed Is Printing a Substituted Line Twice
Cannot Run Rake Db:Migrate, Relation Does Not Exist
Automating Linux Ebs Snapshots Backup and Clean-Up
Using a Command That Needs Backticks to Be Passed as Part of an Argument in Bash
How to Subtract a Year from a Date Stored in a Variable in Shell Script
Communicating Between a Parent and Its Children
How to Concatenate Files with the Same Prefix (And Many Prefixes)
Lazarus: How to List All the Available Network Connection on a System
Bash Tail the Newest File in Folder Without Variable