I launch a docker container from an image with the following command:
$ docker run -d myimage /bin/bash -c "mycommand"
When "mycommand" is finished, the container is stopped (I suppose it is stopped), but it is not deleted, because I can see it with this command:
$ docker ps -a
Is there any way to restart this container with the same parameters and keep data generated by mycommand?
Yes, when the initial command finish its execution then the container stops.
You can start a stopped container using:
docker start container_name
If you want to see the output of your command then you should add -ai options:
docker start -ai container_name
PS. there is a docker restart container_name but that is used to restart a running container - I believe that is not your case.
First, $ docker ps -a shows all containers (the ones that are running and the stopped ones), so that is the reason you are not seeing your stopped container listed.
Second, you can easily start a stopped container running:
$ docker start container_name
Once the container has been started, you can run your command by:
$ docker exec -it container_name bash -c "mycommand"
The stuff you create in your container will remain inside your container as long as it exists. If you want to keep data even if your container is removed you can use a volume.
It should be
$ docker restart container_id # OR
$ docker restart container_name
From the above picture we see one container is up and other status is Exited.
When a container is exited we can still start it back up, because a container stop doesn't mean that it's like dead or cannot be used again we can very easily stop and then start containers again at some point in the future. To start a container backup we can take it's ID and then execute docker start and paste the ID end.
sudo docker start container_id
command for exited container in the above picture will be.
sudo docker start -a bba606a95392
Out put:
By the way: While restarting a container we can not replace the default command, as soon as you started up with the default command is set for the container, for example if we start our container overriding the default command let's see what happened:
Docker is thinking we are trying to start and attach multiple container at the same time.
So when we up a container and let it exit, we can start it back up again which is going to reissue the default command that was used when the container was first created. It is part of docker container lifecycle.
Unfortunately, if you restart your VM/System and it shows
mysql-tls:5.7 "docker-entrypoint.s…" 18 hours ago Exited (255) 44 seconds ago
Answer :
Start the Container
docker start mysql
or
docker start your_container_name
Related
I ran a docker container on one of the terminals, on the other terminal:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
80b6be3a7d56 rbonghi/isaac-ros-tutorial:realsense-camera "/ros_entrypoint.sh …" 9 seconds ago Up 8 seconds inspiring_almeida
and then I run
$ docker attach inspiring_almeida
now nothing seems to happen, cursor moves to a new line.
$ docker attach inspiring_almeida
What am I doing wrong? I expected to see something like root#80b6be3a7d56
P.s. I'm accessing the machine that I run docker via SSH - if that matters.
Run docker exec -it inspiring_almeida /bin/bash. It runs a shell inside the container.
attach just connects your input/output terminal with the container's input/output.
I use following command to build web server
docker run --name webapp -p 8080:4000 mypyweb
When it stopped and I want to restart, I always use:
sudo docker start webapp && sudo docker exec -it webapp bash
But I can't see the server state as the first time:
Digest: sha256:e61b45be29f72fb119ec9f10ca660c3c54c6748cb0e02a412119fae3c8364ecd
Status: Downloaded newer image for ericgoebelbecker/stackify-tutorial:1.00
* Running on http://0.0.0.0:4000/ (Press CTRL+C to quit)
How can I see the state instead of interacting with the shell?
When you use docker run, the default behavior is to run the container detached. This runs in the background and is detached from your shell's stdin/out.
To run the container in the foreground and connected to stdin/out:
docker run --interactive --tty --publish=8080:4000 mypyweb
To docker start a container, similarly:
docker start --interactive --attach [CONTAINER]
NB --attach rather than -tty
You may list (all add --all) running containers:
docker container ls
E.g. I ran Nginx:
CONTAINER ID IMAGE PORTS NAMES
7cc4b4e1cfd6 nginx 0.0.0.0:8888->80/tcp nostalgic_thompson
NB You may use the NAME or any uniquely identifiable subset of the ID to reference the container
Then:
docker stop nostalgic_thompson
docker start --interative --attach 7cc4
You may check the container's logs (when running detached or from another shell) by grabbing the container's ID or NAMES
docker logs nostalgic_thompson
docker logs 7cc4
HTH!
Using docker exec is causing the shell to attach to the container. If you are comparing the behavior of docker run versus docker start, they behave differently, and it is confusing. Try this:
$ sudo docker start -a webapp
the -a flag tells docker to attach stdout/stderr and forward signals.
There are some other switches you can use with the start command (and a huge number for the run command). You can run docker [command] --help to get a summary of the options.
One other command that you might want to use is logs which will show the console output logs for a running container:
$ docker ps
[find the container ID]
$ docker logs [container ID]
If you think your container's misbehaving, it's often not wrong to just delete it and create a new one.
docker rm webapp
docker run --name webapp -p 8080:4000 mypyweb
Containers occasionally have more involved startup sequences and these can assume they're generally starting from a clean slate. It should also be extremely routine to delete and recreate a container; it's required for some basic tasks like upgrading the image underneath a container to a newer version or changing published ports or environment variables.
docker exec probably shouldn't be part of your core workflow, any more than you'd open a shell to interact with your Web browser. I generally don't tend to docker stop containers, except to immediately docker rm them.
(sorry using the term "kill" with quotes is not about docker-compose kill, is about "UNIX ps kill" after what the process really go out of the "UNIX ps list")
Usual docker run can be "killed" by usual docker stop, because after stop I not see the container at docker ps -a... If it is correct, there are a semantic bug with docker-compose because I can't "kill" the containers, they stay at docker ps.
After my simple docker-compose up (without &) I do ^C and the containers stay there at docker ps -a... Impossible to kill by docker compose stop.
NOTE: when I use ordinary docker run and after it docker stop there are nothing at docker ps -a, so I can say "I killed it".
Usual docker run can be "killed" by usual docker stop, because after stop I not see the container at docker ps.
No. docker stop just stops a running container, it doesn' t remove the container. This happens only in case you've used docker run --rm .... This --rm option means that when the container is stopped, it will be removed/deleted.
Docker
docker run ... creates and runs a container
docker stop ... stops a running container
docker start ... starts a stopped container
docker rm ... removes a stopped container
Docker Compose
docker-compose up creates and runs a collection of containers
docker-compose stop stops the containers
docker-compose start starts the containers
docker-compose down stops and removes the containers
Be careful...
As it discussed in the comments section, by using docker-compose down other things can also take place regarding volumes, networks. Keep in mind that you might lose data (if your container is a database for example) and make sure you have saved them or you are somehow able to create them again.
Check out running containers:
docker ps
Example output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e86521d81a96 app_php "docker-php-entrypoi…" 2 hours ago Up About an hour 0.0.0.0:8080->80/tcp app_php_1
7a30681b6255 mysql:5.6 "docker-entrypoint.s…" 3 hours ago Up About an hour 0.0.0.0:3306->3306/tcp app_db_1
21aa3eef5f42 phpmyadmin/phpmyadmin "/run.sh supervisord…" 4 hours ago Up About an hour 9000/tcp, 0.0.0.0:8081->80/tcp app_phpmyadmin_1
9afc52b3f82f mailhog/mailhog "MailHog" 4 hours ago Up About an hour 1025/tcp, 0.0.0.0:8082->8025/tcp app_mailhog_1
then stop one by the container id:
docker kill part_of_the_id/name
For instance:
docker kill e86 or docker kill app_php_1
Docker-compose is just a script to help you manage one or multiple containers running in a group and is absolutely not required to manage your containers.
To remove the container completely you have to remove the container docker rm container_id_or_name
To stop all running containers:
docker stop $(docker ps -q)
You can use docker rm <container-name> to do that. This command will stop and remove service container. Anonymous volumes attached to the container will not be removed.
If command "docker run ubuntu bash" the container won't last.
but if I command "docker run -it ubuntu bash"
the container will make a pseudo-tty and keep this container alive.
my question is
is there any way I can make a Dockerfile for building an image based on ubuntu/centos then I just need to command "docker run my-image" and
the container will last.
apologize for my poor english, I don't know if my question is clear enough.
thanks for any response
There are three ways to run containers:
task containers - do one thing and then exit, like docker run ubuntu ls /
interactive containers - open a connection to the container with -it, like docker run -it ubuntu bash
background containers - keep a container running detached in the background with -d, like docker run -d ubuntu:14.04 ping localhost
Docker keeps the container running as long as there is an active process in the container. The first container exits when the ls command completes. The second container will exit when you exit the bash session. The third container will stay running as long as the ping process keeps running (note that ping has been removed from the recent Ubuntu images, which is why the example specifies 14.04).
In practice to start a container I do:
docker run a8asd8f9asdf0
If thats the case, what does:
docker start
do?
In the manual it says
Start one or more stopped containers
This is a very important question and the answer is very simple, but fundamental:
Run: create a new container of an image, and execute the container. You can create N clones of the same image. The command is:
docker run IMAGE_ID and not docker run CONTAINER_ID
Start: Launch a container previously stopped. For example, if you had stopped a database with the command docker stop CONTAINER_ID, you can relaunch the same container with the command docker start CONTAINER_ID, and the data and settings will be the same.
run runs an image
start starts a container.
The docker run doc does mention:
The docker run command first creates a writeable container layer over the specified image, and then starts it using the specified command.
That is, docker run is equivalent to the API /containers/create then /containers/(id)/start.
You do not run an existing container, you docker exec to it (since docker 1.3).
You can restart an exited container.
Explanation with an example:
Consider you have a game (iso) image in your computer.
When you run (mount your image as a virtual drive), a virtual drive is created with all the game contents in the virtual drive and the game installation file is automatically launched. [Running your docker image - creating a container and then starting it.]
But when you stop (similar to docker stop) it, the virtual drive still exists but stopping all the processes. [As the container exists till it is not deleted]
And when you do start (similar to docker start), from the virtual drive the games files start its execution. [starting the existing container]
In this example - The game image is your Docker image and virtual drive is your container.
run command creates a container from the image and then starts the root process on this container. Running it with run --rm flag would save you the trouble of removing the useless dead container afterward and would allow you to ignore the existence of docker start and docker remove altogether.
run command does a few different things:
docker run --name dname image_name bash -c "whoami"
Creates a Container from the image. At this point container would have an id, might have a name if one is given, will show up in docker ps
Starts/executes the root process of the container. In the code above that would execute bash -c "whoami". If one runs docker run --name dname image_name without a command to execute container would go into stopped state immediately.
Once the root process is finished, the container is stopped. At this point, it is pretty much useless. One can not execute anything anymore or resurrect the container. There are basically 2 ways out of stopped state: remove the container or create a checkpoint (i.e. an image) out of stopped container to run something else. One has to run docker remove before launching container under the same name.
How to remove container once it is stopped automatically? Add an --rm flag to run command:
docker run --rm --name dname image_name bash -c "whoami"
How to execute multiple commands in a single container? By preventing that root process from dying. This can be done by running some useless command at start with --detached flag and then using "execute" to run actual commands:
docker run --rm -d --name dname image_name tail -f /dev/null
docker exec dname bash -c "whoami"
docker exec dname bash -c "echo 'Nnice'"
Why do we need docker stop then? To stop this lingering container that we launched in the previous snippet with the endless command tail -f /dev/null.
daniele3004's answer is already pretty good.
Just a quick and dirty formula for people like me who mixes up run and start from time to time:
docker run [...] = docker pull [...] + docker start [...]
It would have been wiser to name the command "new" instead of "run".
Run creates a container instance of an existing (or downloadable) image and starts it.