firstpostcommenter
firstpostcommenter

Reputation: 2931

Docker -it command is related to a Docker image or Docker container

I am new to Docker and am trying to learn about Docker using 101-tutorial docker image(https://github.com/dockersamples/101-tutorial)

enter image description here

In this lesson, they were trying to explain that when 2 container instances are run from the same image then the data created by the first container is not available in the 2nd container by default (unless we are using container volumes and mounting, etc).

1st and 2nd points shows that an ubuntu container is running and has a file called data.txt.

As per my understanding, docker -it is used for getting access to terminal inside a docker container. https://docs.docker.com/engine/reference/run/

But I don't understand the command used in 3rd point. Why is docker run -it ubuntu ls / command run on Ubuntu image rather than on a container using Container ID? Is the command used for just showing the contents inside an image instead of showing contents inside a docker container using ls /?

I expected that 3rd point should have created another container instance and then run ls / but as per docker ps I see that there is only one ubuntu container running in my machine.

Upvotes: 3

Views: 5079

Answers (3)

firstpostcommenter
firstpostcommenter

Reputation: 2931

I see the question is about docker run imagename command.

TLDR:- You don't see the docker container because the docker container was created and started and then exited immediately. Why? Because it all comes down to the CMD command that is given in the Dockerfile which is used to build the docker image that you are trying to run (ubuntu docker image in this case).


Some background about Docker and docker run command:-

In your case, when you ran the docker run ubuntu command then the docker container is created and started and then exited immediately so you wont see it in docker ps container list but you can see it in docker ps -a command result with exited status.

This is because Containers are meant to run a specific task or process such as to host an instance of a web sever or application server or database or simply to carry out some kind of computation or analysis.

Once the task is complete the container exits. The container only lives as long as the process inside it is alive. If the WebService inside the container is stopped or crashes then the container exits.

So who defines what process is run within the container?

If we look at the dockerfile for popular docker images like nginx we will see an instruction called CMD which stands for command that defines the program that will be run within the container when it starts.

For the nginx image it is the nginx command, for the mysql image it is the mysqld command.

What you tried to do earlier was to run a container with an Ubuntu image and if we see the dockerfile for that image (Ubuntu Docker image's dockerfile) we will see that it uses bash as the default command in the CMD line. Now bash is not really a process like a webserver or database server. It is a shell that listens for inputs from a terminal and if it cannot find a terminal it exits. So when you ran the image earlier then Docker created a container from the image and launched the bash program. By default docker does not attach a terminal to a container when it is run and so the bash program does not find the terminal and it exits. Since the process that was started when the container was created finished so the container exits as well.

So how do we specify a different command to start the container?

One option is to append a command to the docker run command and that way it overrides the default command specified within the image. For example docker run ubuntu sleep 5 with the sleep 5 command as the added option. This way when the container starts it runs the sleep program so waits for 5 seconds and then exits. But how do we make that change permanent. Say we want the image to always run the sleep command when it starts. we should then create our own image from the base ubuntu image and specify a new command.

Dockerfile,

Using CMD instruction,

FROM Ubuntu
CMD sleep 5

or Using both the Entrypoint and CMD instruction which is better,

FROM Ubuntu
ENTRYPOINT ["sleep"]
CMD ["5"]

So we can now build the new image using docker build command and name it as ubuntu-sleeper or something like that. we can now simply run the docker run ubuntu-sleeper command and get the same result where it always sleeps for 5 seconds and exits

Upvotes: 0

aryanveer
aryanveer

Reputation: 666

Docker containers are completely isolated from each other. When you create a container using an image, a small section of resources from your system are isolated with the help of namespacing and cgroups, and then the files in the image are copied inside the resources of this isolated environment.

When you execute the command docker run -it ubuntu ls /, it creates a new container, runs the specified command ls / and gives u an interactive tty to the docker container using the -i and -t flag.

After running this process and showing you the output, the container exited immediately, thus nothing showing in output of docker ps. In order to check the container created, run the docker ps --all command.

Upvotes: 3

daniu
daniu

Reputation: 15028

As it says in the documentation for docker run:

Docker runs processes in isolated containers. A container is a process which runs on a host. The host may be local or remote. When an operator executes docker run, the container process that runs is isolated in that it has its own file system, its own networking, and its own isolated process tree separate from the host.

After the process is finished, the container will be shut down.

As for your question whether it "refers to an image or a container" - you give the image as an argument to create the container, then runs the process in the created container.

The lifecycle of a Docker container is:

  • docker run imagename -> create container x from image imagename
  • docker exec x ls -> execute command ls in running container x
  • docker stop x -> stop container (but still visible in docker container ls -a)
  • docker start x -> restart container x
  • docker stop x -> stop container xagain
  • docker rm x -> remove container x (now also ls -a won't show it)

Upvotes: 3

Related Questions