Difference between Running and Starting a Docker container - docker

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.

Related

How to see the docker state instead of interacting with the shell?

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.

Docker container keeps stopping after 'docker start'

I'm fairly new to Docker. I have a long Dockerfile that I inherited from a previous developer, which has many errors and I'm trying to get it back to a working point. I commented out most of the file except for just the first line:
FROM ubuntu:14.04
I did the following:
docker build -t pm . to build the image - this works because I can see the image when I execute docker images
docker run <image-id> returns without error or any message. Now I'm expecting the container to be created from the image and started. But when I do a docker ps -a it shows the container exited:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b05f9727f516 f216cfb59484 "/bin/bash" About a
minute ago Exited (0) About a minute ago
lucid_shirley
Not sure why can't I get a running container and why does it keep stopping after the docker run command.
executing docker logs <container_id> displays nothing - it just returns without any output.
Your Docker image doesn’t actually do anything, container stop when finish its job. Since here no foreground process running it will start and then immediately stop.
To confirm your container have no issues, try to put below code into a docker-compose.yml(in same folder as the Dockerfile) and run docker-compose up, now you will see your container is running without exiting.
version: '3'
services:
my-service:
build: .
tty: true
Please have a look here Docker official tutorial it will guide you to how to work with docker.
try
docker run -it <image> /bin/bash
to run a shell inside the container.
That won't do much for you, but that'll show you what is happening: as soon as you exit the shell, it will exit the container too.
Your container basically doesn't do anything: it has an image of Ubuntu but doesn't have an ENTRYPOINT or a CMD command to run 'something'
Containers are ephemeral when ran: they run a single command and exit when the command finishes.
Docker container categorized following way.
Task Based : When container start it will start processing and it complete the process then exited.
Background container : It will wait for some request.
As you not provided your docker file so I assume that you have only one statement.
FROM ubuntu:14.04
your build statement create image with name pm.
Now you run
docker run pm
It will start container and stop as you did not provide any entry point.
Now try this
This is one command prompt or terminal.
docker run -it pm /bin/bash
Open another terminal or command prompt.
docker ps ( Now you will see there is one container).
If you want to see container that is continuously running then use following image.
(This is just a example)
docker run -d -p 8099:80 nginx
Above line run one container with Nginx image and when you open your browser http://localhost:8099 you can see the response.
Docker Containers are closely related to the process they are running. This process is specified by the "CMD" part on the Dockerfile. This process has the PID "1". If you kill it, your container is killed. If you haven't one, your container will stop instantly. In your case, you have to "override" your CMD. You can do it with a simple : "docker run -it ubuntu:18.04 bash". "-it" is mandatory since it allows the stdin to be attached to your container.
Have fun with docker.
Each instruction of Dockerfile is a layer within a container which perform some task. In your docker file It's just the loading the ubuntu which is completed when you run the docker within a fraction of seconds and exit since process finished. So if want to have your container running all the time then there should be a foreground process running in your docker.
For testing if you run
docker run <imageid> echo hi it will return the output means your container is fine.

docker run vs create+start: why are created containers different?

Related to
docker container started in Detached mode stopped after process execution
https://serverfault.com/questions/661909/the-right-way-to-keep-docker-container-started-when-it-used-for-periodic-tasks
I do understand the difference between docker run and create + start, but don't understand how the actual containers created in these two ways differ.
Say I create and run a container with
docker run -dit debian:testing-slim
and then stop it. The created container can later be started with
docker start silly_docker_name
and it'll run in the background, because the entry command for the image is bash.
But when a container is first created
docker create --name silly_name debian:testing-slim
and then started with
docker start silly_name
then it'll exit immediately. Why isn't bash started, or how come it exits in this case?
The difference for a container process that is a shell (like bash in your debian example) is that a shell started without a terminal+interactive "mode" exits without doing anything.
You can test this by changing the command of a create'd container to something that doesn't require a terminal:
$ docker create --name thedate debian date
Now if I run thedate container, each time I run it it outputs the date (in the logs) and exits. docker logs thedate will show this; one entry for each run.
To be explicit, your docker run command has flags -dit: detached, interactive (connect STDIN), and tty are all enabled.
If you want a similar approach with create & start, then you need to allocate a tty for the created container:
$ docker create -it --name ashell debian
Now if I start it, I ask to attach/interactively to it and I get the same behavior as run:
$ docker start -ai ashell
root#6e44e2ae8817:/#
NOTE: [25 Jan 2018] Edited to add the -i flag on create as a commenter noted that as originally written this did not work, as the container metadata did not have stdin connected at the create stage

Docker run vs create

What is the difference between docker run and docker create commands?
I usually use run but sometimes in documentation I see create.
Docker's --help tells
create Create a new container
run Run a command in a new container
Does it mean that run is used when we need to pass a command to a new container? What's the aim of create then?
docker run = docker create + docker start.
From docker documentation
The docker create command creates a writeable container layer over the
specified image and prepares it for running the specified command. The
container ID is then printed to STDOUT. This is similar to docker run
-d except the container is never started. You can then use the docker start command to start the container at any point.
This is useful when you want to set up a container configuration ahead
of time so that it is ready to start when you need it. The initial
status of the new container is created.
docker create command creates a writeable container from the image and prepares it for running.
docker run command creates the container (same as docker create) and starts it.
The other answers have this covered but I thought I'd show the equivalent shell command-lines because it makes it really clear:
$ docker run myimage
is the same as
$ docker start -a $(docker create myimage)
Here, docker create is used to create a container from the named image and outputs the created container id and docker start is used to start the container with that id. The -a option causes the terminal to attach so that the container runs in the foreground which is the default behaviour of docker run.
A container that has been created but never started will have a Created status; this can be seen with docker container ls -a.
I'm new to docker and just got around to playing with it;
My take is that docker run essentially does the following: (in the order of..) docker create, docker start, docker attach , since it immediately attaches to the active shell after you do the 'run' command.
to create a container:
to start a container:
to create and start with a single command:
Now to understand we must dig deep with create and start.
Process of creating a container is taking the file system from image, and kind of prep it for use in the new container. When we create the container we are just prepping or setting up the file system snapshot to be used to create the container to actually start the container.
So creating container is about the file system starting it is about actually executing the startup the command.
And to start the container, we actually execute the start up command that might start up the process.
Lets see it in terminal:
When I run command "sudo docker create hello-world" it prints bellow output.
In the output we saw characters printed out. This is the ID of the container that was just created, Now I can actually execute the hello world command inside of this container by running Docker start.
So what happened here, first off we kind of prop the container by getting the file system ready.
Then after that we actually executed the primary start up command in there with Docker start.
-a in the docker start command is for watching output from the container and print it out to your terminal.
So there is very small difference between Docker run and docker start, by default Docker run is going to show you all the logs or all the information coming out of the container. By default Docker start is the opposite Docker start is not going to show you information coming out of the terminal.
Now you know when you need to use Run / Create / Start
Docker run is basically for running commands in the container.
docker run -it <Container Name> /bin/bash
The above is for creating a bash terminal. And make us use bash commands in the container.
Docker create is to create a container from an Docker Image.
docker create -d /var/lib:/var/lib --name docker-ubuntu ubuntu
The above is to create a docker a container of the name "docker-ubuntu" from the image "ubuntu"

How to keep the docker container up and running?

Here is my simple docker file
FROM java:8
EXPOSE 4000
now when I run it using the following command
sudo docker run --name hello dockerfile
and do docker ps -a it shows the status as exited. I just want to keep this container up and running so I can ssh into this container and probably transfer files and so on. It looks like containers are mainly used to run servers am I correct?
you can at least keep your container up with something like docker run -d hello sleep infinity but as said by René M, you should put in your Dockerfile something to do in your CMD or ENTRYPOINT, see the doc
https://docs.docker.com/engine/reference/builder/#cmd
and
https://docs.docker.com/engine/reference/builder/#entrypoint
That is realy simple.
Because your container is running nothing that last long. What happens is, that this container starts, has nothing to do and stops.
What you can do is:
Run the container in interactive mode with attached tty. This way your console enters the container after it's start, and let him run a tty, which is something to do and prevends the container from stopping. Then you can work inside this container, like installing an application. Doing this your work will be lost after stoping the container. But you can run docker commit on that container, which makes your changes persistent.
docker run -i -t --name hello dockerfile
Enhance your dockerfile with something usefull. Like copying an application into the container and provide a CMD command to run, when the container starts.
After this the container will last as long as your CMD command runs. If the command is a server or deamon application, the container will last for ever and will only stop when you stop him.

Resources