Both will be able to execute commands in container. Both could detach the container.
So what is the real difference between the docker exec
and docker attach
commands?
2015: There was a commit PR which added to the doc:
Note: This command (
attach
) is not for running a new process in a container. See:docker exec
.
The answer to "Docker. How to get bash\ssh inside ran container (run -d
)?" illustrates the difference:
(docker >= 1.3) If we use
docker attach
, we can use only one instance of shell (See Manuel Jordan's answer on that).
So if we want to open a new terminal with new instance of container's shell, we just need to rundocker exec
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 usingexec
.
As mentioned in this issue:
- Attach isn't for running an extra thing in a container, it's for attaching to the running process.
- "
docker exec
" is specifically for running new things in a already started container, be it a shell or some other process.
The same issue adds:
While
attach
is not well named, particularly because of the LXC commandlxc-attach
(which is more akindocker exec <container> /bin/sh
, but LXC specific), it does have a specific purpose of literally attaching you to the process Docker started.
Depending on what the process is, the behavior may be different, for instance attaching to/bin/bash
will give you a shell, but attaching to Redis-server will be like you'd just started Redis directly without daemonizing.
Update 2022: See more with "Containers 101: attach vs. exec - what's the difference?" (Dec. 2021) from Ivan Velichko:
Extract:
Difference between attach and logs
On the diagram above,
docker attach
streams the container's logs back to the terminal.
However, thedocker logs
command does a similar thing.
So, what's the difference?The logs command provides various options to filter the logs while attach in that regard acts as a simple tail.
But what's even more important is that the stream established by the logs command is always unidirectional and connected to the container's logs, not the container's stdio streams directly.The logs command simply streams the content of the container's logs back to your terminal, and that's it.
So, regardless of how you created your container (interactive or non-interactive, controlled by a pseudo-terminal or not), you cannot accidentally impact the container while using the logs command.However, when attach is used:
- If a container was created in the interactive mode (
-i
), everything you type in the terminal after attach-ing to the container will be sent to its stdin.- You can (intentionally or accidentally) send a signal to the container - for instance, hitting ctrl+c on your end while attached sends
SIGINT
to the container.What does exec command do
The exec command is actually a totally different story.
In the case of attach, we were connecting our terminal to an existing container (read, process).
However, the
exec
commandstarts a totally new container!
In other words,exec
is a form of therun
command (which itself is just a shortcut forcreate
+start
).
Bart reminds us in the comments that docker exec
runs a new command in a running container. Not a "totally new one".