I have a fundamental question about container life cycle.
For example I run the following command
Create new ubuntu container and run the bash command
docker run -it ubuntu bash
In the container's bash
exit
The new container will be in state EXITED
docker ps -a
Then I use docker start to restart the container
docker start xxxx(container name)
docker exec -it xxxx(container name) /bin/bash
In the restarted container's bash
exit
The restarted container is still running
docker ps -a
May I know the reason behind for this behavior? Thank you!
With the docker run command:
docker run -it ubuntu bash
the container is started with the execution of the bash command, so when you exit from the bash, the container also exits as bash is the main process running inside the container.
However with the docker exec command:
docker exec -it xxxx(container name) /bin/bash
the container is already running the command defined by the CMD/ENTRYPOINT and bash is the command executed as a separate process. So, exiting from bash after docker start exits the bash process and the main process is still continued.
'docker exec' can only used on running container, but what is the meaning of running container? Is that means the container should be computing something? or is the issue about the [command] which I define for the container? Why my TensorFlow container always be stopped status?
After I used 'docker run' to build a tensorflow container, the container stopped automatically. I need to restart it and then execute command on it. Why the container cannot be always in running since I build it?
docker run -it --runtime=nvidia tensorflow/tensorflow:latest-gpu-py3
It will then pops up a bash which I can use to control the container. But after I exit, the container stopped itself. Which means, I can only use docker ps -a to see my container but docker pscan not. I have to restart the container if I want to use my container again.
UPDATE1: If I want create a container like VM, I cannot use docker run with a temporal [command] like python ... The container will lose control permanently after the command finished. docker restart cannot start the container again. Hence, docker exec cannot apply on it. Instead, using bash or nothing as the [command] can create a container which can be restart, therefore, can be applied withdocker exec.
UPDATE2: docker run -d -it can create a running container (but the bash shell won't pops up, neither even with bash). Directly using docker exec -it container_name bash can take the control of the running container again, without docker restart. In this time, exiting bash shell will not stop the container.
A container is running when there is an active process running inside it.
When you are running this tensorflow container, it will exit due to there being no running process
If you were to run
docker run -it --runtime=nvidia tensorflow/tensorflow:latest-gpu-py3 bash
or
docker run -it --runtime=nvidia tensorflow/tensorflow:latest-gpu-py3 python <python script name>
then the container would run the bash/python script as a process and therefore remain up whilst that process is running
View running processes with:
docker ps
See all containers (including stopped/exited tasks) with:
docker ps -a
The difference between docker ps -a and docker ps is exactly what you are looking for:
From the documentation:
--all , -a Show all containers (default shows just running)
So
docker ps gives you only running container
docker ps -a also shows you the stopped ones
So probably, if you expect you container to be long running, (like it would for a web server), then indeed your container command could have an issue and is not keeping your container alive.
Also mind that, if you run your container with the options -ti, like you did, you get an interactive tty attached to it.
--tty , -t Allocate a pseudo-TTY
--interactive , -i Keep STDIN open even if not attached
That basically means that, as soon as you exit that interactive context, your container will shut down.
Running it in a detached mode, with the options -d, is maybe what you are looking for
docker run -d --runtime=nvidia tensorflow/tensorflow:latest-gpu-py3
Related documentation:
--detach , -d Run container in background and print container ID
https://docs.docker.com/engine/reference/commandline/run/
docker pull httpd
..
docker run -d --name MyWebServer httpd
..
docker attach MyWebServer
(nothing printed here - so I press enter + ls)
ls
(nothing printed here - so I press enter multiple times and still nothing..)
When I try to do the same thing with ubuntu image, it works. Why it isn't working here?
The difference is the running process. With Ubuntu, you are being attached to the sh. With httpd you are being attached to the apache main process, which is not a shell.
Do this instead of attach:
docker exec -it MyWebServer sh
With that, you are launching a shell inside the same container that runs apache process.
Have you read the docs? The attach returns any messages that the container produces. I bet you wanted to do the exec instead.
It’s either
docker exec -it container_name_or_id bash
or
docker-compose exec service_name bash
if you use the docker-compose app.
You can execute any command (unless the container has no fixed entrypoint), for instance
docker exec container ls /
If I run a command using docker's exec command, like so:
docker exec container gulp
It simply runs the command, but nothing is outputted to my terminal window.
However, if I actually go into the container and run the command manually:
docker exec -ti container bash
gulp
I see gulp's output:
[13:49:57] Using gulpfile ~/code/services/app/gulpfile.js[13:49:57]
Starting 'scripts'...[13:49:57] Starting 'styles'...[13:49:58]
Starting 'emailStyles'... ...
How can I run my first command and still have the output sent to my terminal window?
Side note: I see the same behavior with npm installs, forever restarts, etc. So, it is not just a gulp issue, but likely something with how docker is mapping the stdout.
How can I run my first command and still have the output sent to my terminal window?
You need to make sure docker run is launched with the -t option in order to allocate a pseudo tty.
Then a docker exec without -t would still work.
I discuss docker exec -it here, which references "Fixing the Docker TERM variable issue ")
docker#machine:/c/Users/vonc/prog$ d run --name test -dit busybox
2b06a0ebb573e936c9fa2be7e79f1a7729baee6bfffb4b2cbf36e818b1da7349
docker#machine:/c/Users/vonc/prog$ d exec test echo ok
ok
I created a container with -d so it's not interactive.
docker run -d shykes/pybuilder bin/bash
I see that the container has exited:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d6c45e8cc5f0 shykes/pybuilder:latest "bin/bash" 41 minutes ago Exited (0) 2 seconds ago clever_bardeen
Now I would like to run occasional commands on the machine and exit. Just to get the response.
I tried to start the machine. I tried attaching. I thought I could call run with a container, but that does not seem to be allowed. Using start just seems to run and then exist quickly.
I'd like to get back into interactive mode after exiting.
I tried:
docker attach d6c45e8cc5f0
But I get:
2014/10/01 22:33:34 You cannot attach to a stopped container, start it first
But if I start it, it exits anyway. Catch 22. I can't win.
In October 2014 the Docker team introduced docker exec command: https://docs.docker.com/engine/reference/commandline/exec/
So now you can run any command in a running container just knowing its ID (or name):
docker exec -it <container_id_or_name> echo "Hello from container!"
Note that exec command works only on already running container. If the container is currently stopped, you need to first run it with the following command:
docker run -it -d shykes/pybuilder /bin/bash
The most important thing here is the -d option, which stands for detached. It means that the command you initially provided to the container (/bin/bash) will be run in the background and the container will not stop immediately.
Your container will exit as the command you gave it will end. Use the following options to keep it live:
-i Keep STDIN open even if not attached.
-t Allocate a pseudo-TTY.
So your new run command is:
docker run -it -d shykes/pybuilder bin/bash
If you would like to attach to an already running container:
docker exec -it CONTAINER_ID /bin/bash
In these examples /bin/bash is used as the command.
So I think the answer is simpler than many misleading answers above.
To start an existing container which is stopped
docker start <container-name/ID>
To stop a running container
docker stop <container-name/ID>
Then to login to the interactive shell of a container
docker exec -it <container-name/ID> bash
To start an existing container and attach to it in one command
docker start -ai <container-name/ID>
Beware, this will stop the container on exit. But in general, you need to start the container, attach and stop it after you are done.
To expand on katrmr's answer, if the container is stopped and can't be started due to an error, you'll need to commit it to an image. Then you can launch bash in the new image:
docker commit [CONTAINER_ID] temporary_image
docker run --entrypoint=bash -it temporary_image
Some of the answers here are misleading because they concern containers that are running, not stopped.
Sven Dowideit explained on the Docker forum that containers are bound to their process (and Docker can't change the process of a stopped container, seemingly due at least to its internal structure: https://github.com/docker/docker/issues/1437). So, basically the only option is to commit the container to an image and run it with a different command.
See https://forums.docker.com/t/run-command-in-stopped-container/343
(I believe the "ENTRYPOINT with arguments" approach wouldn't work either, since you still wouldn't be able to change the arguments to a stopped container.)
I had to use bash -c to run my command:
docker exec -it CONTAINER_ID bash -c "mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql mysql"
Creating a container and sending commands to it, one by one:
docker create --name=my_new_container -it ubuntu
docker start my_new_container
// ps -a says 'Up X seconds'
docker exec my_new_container /path/to/my/command
// ps -a still says 'Up X+Y seconds'
docker exec my_new_container /path/to/another/command
If you are trying to run shell script, you need run it as bash.
docker exec -it containerid bash -c /path/to/your/script.sh
This is a combined answer I made up using the CDR LDN answer above and the answer I found here.
The following example starts an Arch Linux container from an image, and then installs git on that container using the pacman tool:
sudo docker run -it -d archlinux /bin/bash
sudo docker ps -l
sudo docker exec -it [container_ID] script /dev/null -c "pacman -S git --noconfirm"
That is all.
Pipe a command to docker exec bash stdin
Must remove the -t for it to work:
echo 'touch myfile' | docker exec -i CONTAINER_NAME bash
This can be more convenient that using CLI options sometimes.
Tested with:
docker run --name ub16 -it ubuntu:16.04 bash
then on another shell:
echo 'touch myfile' | docker exec -i ub16 bash
Then on first shell:
ls -l myfile
Tested on Docker 1.13.1, Ubuntu 16.04 host.
I would like to note that the top answer is a little misleading.
The issue with executing docker run is that a new container is created every time. However, there are cases where we would like to revisit old containers or not take up space with new containers.
(Given clever_bardeen is the name of the container created...)
In OP's case, make sure the docker image is first running by executing the following command:
docker start clever_bardeen
Then, execute the docker container using the following command:
docker exec -it clever_bardeen /bin/bash
I usually use this:
docker exec -it my-container-name bash
to continuously interact with a running container.
Assuming the image is using the default entrypoint /bin/sh -c, running /bin/bash will exit immediately in daemon mode (-d). If you want this container to run an interactive shell, use -it instead of -d. If you want to execute arbitrary commands in a container usually executing another process, you might want to try nsenter or nsinit. Have a look at https://blog.codecentric.de/en/2014/07/enter-docker-container/ for the details.
Unfortunately it is impossible to override ENTRYPOINT with arguments with docker run --entrypoint to achieve this goal.
Note: you can override the ENTRYPOINT setting using --entrypoint, but
this can only set the binary to exec (no sh -c will be used).
For Mac:
$ docker exec -it <container-name> sh
if you want to connect as root user:
$ docker exec -u 0 -it <container-name> sh
Simple answer: start and attach at the same time. In this case you are doing exactly what you asked for.
docker start <CONTAINER_ID/CONTAINER_NAME> && docker attach <CONTAINER_ID/CONTAINER_NAME>
make sure to change <CONTAINER_ID/CONTAINER_NAME>
I am running windows container and I need to look inside the docker container for files and folder created and copied.
In order to do that I used following docker entrypoint command to get the command prompt running inside the container or attach to the container.
ENTRYPOINT ["C:\\Windows\\System32\\cmd.exe", "-D", "FOREGROUND"]
That helped me both to the command prompt attach to container and to keep the container a live. :)
# docker exec -d container_id command
Ex:
# docker exec -d xcdefrdtt service jira stop
A quick way to resume and access the most recently exited container:
docker start -a -i `docker ps -q -l`
An easy solution that solved a similar problem for me:
docker run --interactive --tty <name_of_image>