> For the complete documentation index, see [llms.txt](https://amanalok.gitbook.io/mlops/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://amanalok.gitbook.io/mlops/docker/introduction-to-docker.md).

# Introduction to Docker

After installing Docker, one can check its version by the following command:

```bash
docker version
```

The output of the above command would be somethign like below:

```bash
Client:
 Cloud integration: v1.0.25
 Version:           20.10.16
 API version:       1.41
 Go version:        go1.17.10
 Git commit:        aa7e414
 Built:             Thu May 12 09:20:34 2022
 OS/Arch:           darwin/arm64
 Context:           default
 Experimental:      true

Server: Docker Desktop 4.9.1 (81317)
 Engine:
  Version:          20.10.16
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.10
  Git commit:       f756502
  Built:            Thu May 12 09:14:19 2022
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.4
  GitCommit:        212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
 runc:
  Version:          1.1.1
  GitCommit:        v1.1.1-0-g52de29d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

```

## Hello World

We would execute the following command now:

```bash
docker run hello-world
Hello from Docker!
```

For the above command, docker takes the following steps:

* The Docker client contacted the Docker daemon.
* The Docker daemon pulled the "hello-world" image from the Docker Hub. (arm64v8)
* The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading.
* The Docker daemon streamed that output to the Docker client, which sent it to your terminal.

## Docker CLI

### docker run

The first command we would look in details is the `docker run` command. The below figure provides details about this command:

![](/files/qHqCZw9xT4XVZ4BFtE5J)

The `docker run` command is used for creating and running a container from an image.

### Overriding Default Commands

To override the default startup command, the following figure shows how to do it:

![](/files/BWbaDFLBwyTiwequJQT2)

For example, following command uses a override command with `docker run`:

```bash
docker run busybox echo hi there
```

Output would be:

```bash
hi there
```

Another example is listing out the files and directories within a container:

```bash
docker run busybox ls
```

Output of the above command would be:

```bash
bin        dev        etc        home       proc
root       sys        tmp        usr        var
```

Now, let's try the `echo` and `ls` override commands with the `hello-world` image with `docker run`.

```bash
docker run hello-world ls
docker: Error response from daemon: failed to create shim task: OCI runtime create 
failed: runc create failed: unable to start container process: exec: "ls": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 

docker run hello-world echo hi there
docker: Error response from daemon: failed to create shim task: OCI runtime create 
failed: runc create failed: unable to start container process: exec: "echo": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled 
```

As we can observe, we get an error for both the commands. This is because inside the `hello-world` image file-system, the `ls` and `echo` programs do not exist. The only thing that exists inside the `hello-world` image snaphot file-system is a single program. All this program does is print out the singular message: `Hello from Docker!`.

The same commands work with the `busybox` image because these programs exist inside the `busybox` file-system image.

### Listing Running Containers

Next, we will look at a command to list all currently running containers on a local machine.

![](/files/kzEOGD1mPzTUKtnBmVjf)

First of all we will run a container for a meaningful amount of time, like below:

```bash
docker run busybox ping google.com

PING google.com (172.217.161.14): 56 data bytes
64 bytes from 172.217.161.14: seq=0 ttl=37 time=11.497 ms
64 bytes from 172.217.161.14: seq=1 ttl=37 time=12.000 ms
64 bytes from 172.217.161.14: seq=2 ttl=37 time=18.183 ms
64 bytes from 172.217.161.14: seq=3 ttl=37 time=13.093 ms
64 bytes from 172.217.161.14: seq=4 ttl=37 time=11.236 ms
```

Next, we would list the running containers:

```bash
docker ps

CONTAINER ID   IMAGE     COMMAND             CREATED         STATUS         PORTS     NAMES
b60202284ace   busybox   "ping google.com"   2 minutes ago   Up 2 minutes             exciting_tharp
```

As can be observed from the output of the command, it prints out a bunch of information about the running container.

We can modify the `docker ps` command to list all containers created on a local machine like the following:

```bash
docker ps --all
```

Executing the above command will give the output something like below:

```bash
CONTAINER ID   IMAGE         COMMAND             CREATED       STATUS                   PORTS     NAMES
b60202284ace   busybox       "ping google.com"   3 hours ago   Exited (0) 3 hours ago             exciting_tharp
298176ed2948   hello-world   "/hello"            3 hours ago   Exited (0) 3 hours ago             zen_johnson
38f01afc355f   hello-world   "echo hi there"     3 hours ago   Created                            distracted_austin
b25255cc9ef7   hello-world   "ls"                3 hours ago   Created                            awesome_swirles
b09147ec3aae   busybox       "ls"                4 hours ago   Exited (0) 4 hours ago             youthful_wu
ab8b6c0bf713   busybox       "echo hi there"     4 hours ago   Exited (0) 4 hours ago             wonderful_archimedes
9435b6d0c6f7   hello-world   "/hello"            5 hours ago   Exited (0) 5 hours ago             xenodochial_kepler
```

### Container Lifecycle

The `docker run` command is actually equivalent to running 2 seperate commands as detailed below:

![](/files/wMRbGJKcfwBBKYyLcApv)

The `docker create` command creates a container while the `docker start` command starts a container:

![](/files/4bwHqjUbRhiB9LxlJj28)

For example, the below command creates a new container using the `hello-world` image:

```bash
docker create hello-world

43b0148310bad8560734d780be5b7f7aac788b646a046efaa93e50d4558395d9
```

As can be observed, the `docker create` command outputs the id of the container that was created.

Next, we can execute the `hello world` command inside of this container using `docker start`, like below:

```bash
docker start -a 43b0148310bad8560734d780be5b7f7aac788b646a046efaa93e50d4558395d9
```

Like running the `docker run` command, the above command will output the following:

```bash
Hello from Docker!
```

Running `docker start` without the `-a` arguement does the following:

```bash
docker start 43b0148310bad8560734d780be5b7f7aac788b646a046efaa93e50d4558395d9

43b0148310bad8560734d780be5b7f7aac788b646a046efaa93e50d4558395d9
```

As can be observed above, without the `-a` argement, the command returns back the id of the container. The `-a` arguement will make docker actually watch for output from the container and print it out on the terminal.

### Restarting Stopped Containers

An exited container can be started back again. For example, first we list all the containers created on a machine like below:

```bash
CONTAINER ID   IMAGE         COMMAND             CREATED          STATUS                     PORTS     NAMES
43b0148310ba   hello-world   "/hello"            16 minutes ago   Exited (0) 9 minutes ago             serene_poincare
b60202284ace   busybox       "ping google.com"   3 hours ago      Exited (0) 3 hours ago               exciting_tharp
298176ed2948   hello-world   "/hello"            3 hours ago      Exited (0) 3 hours ago               zen_johnson
38f01afc355f   hello-world   "echo hi there"     4 hours ago      Created                              distracted_austin
b25255cc9ef7   hello-world   "ls"                4 hours ago      Created                              awesome_swirles
b09147ec3aae   busybox       "ls"                4 hours ago      Exited (0) 4 hours ago               youthful_wu
ab8b6c0bf713   busybox       "echo hi there"     4 hours ago      Exited (0) 4 hours ago               wonderful_archimedes
9435b6d0c6f7   hello-world   "/hello"            5 hours ago      Exited (0) 5 hours ago               xenodochial_kepler
```

Then, let's say we pick the seventh entry (second last) from the list. Using the container id, we can issue the following command to start the container again.

```bash
docker start -a ab8b6c0bf713

hi there
```

One thing to note is that we cannot modify the start command for a container which has been already created. For example,

```bash
docker start -a ab8b6c0bf713 echo bye there

you cannot start and attach multiple containers at once
```

As can be observed, docker misinterprets the command and throws an error.

### Removing Stopped Containers

To remove all containers, following is the command:

```bash
docker system prune

WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
43b0148310bad8560734d780be5b7f7aac788b646a046efaa93e50d4558395d9
b60202284acedd38ed38988290017182071b2fc152ab14414dce96435a5ae749
298176ed29480b90d5ac928ec1d8b8c474c9dd04941c4fdf8f7387632a36d670
38f01afc355fc6bdc96dec59b560cfcce81302e8a3939f0e55bf48bafc2a10c7
b25255cc9ef76f1bdd6ca4317f388ebff7890b526f2817292b2dc4264fe7f7a1
b09147ec3aaeb26d8e396564ee2638178048da49b7d0623d40606c77be56bf6b
ab8b6c0bf7138516fd84ccd78c3352515549df6012a90540720437443cf587c6
9435b6d0c6f71a5db9eb23f93a863a33a8b269e2179d1c7ccb71fb36a1899ee5

Total reclaimed space: 0B
```

As can be observed above, before removing all the stopped containers, docker outputs a warning and requests a confirmation from the user to actually remove the stopped containers.

### Retrieving Log Outputs

Another way of getting the output from a container without using the `-a` flag with `docker start` is using the `docker logs` command. Specifically, below is the command to get logs from a container.

![](/files/3BO8Y74rEfjvjPeDmlFL)

Following is the series of command that shows usage of `docker logs` command:

```bash
docker create busybox echo hi there
1a75b9eec51c364c71d12cfbeb96d3e6adc6789a4551a2de6ae22a72fe3d954c

docker start 1a75b9eec51c364c71d12cfbeb96d3e6adc6789a4551a2de6ae22a72fe3d954c
1a75b9eec51c364c71d12cfbeb96d3e6adc6789a4551a2de6ae22a72fe3d954c

docker logs 1a75b9eec51c364c71d12cfbeb96d3e6adc6789a4551a2de6ae22a72fe3d954c
hi there
```

### Stopping Containers

There are 2 ways of stopping a running container:

![](/files/oy9s7Aa4KW6tEsxpCOA4)

Both the above commands are going to stop a running container. While both these commands kind of do the same thing, internally there is a difference between them.

When `docker stop` command is issued, a hardware signal SIGTERM is sent to the primary process inside the concerned container. This message tells the container to shutdown on its own time.

On the other hand, the `docker kill` command issues a SIGKILL signal to the primary process inside the concerned container. SIGKILL essentially means the conatiner has to shutdown right away without doing any additional work.

Ideally, `docker stop` should be used to stop a container. If a container is non-responsive, we can use `docker kill` command instead.

One thing to note about the `docker stop` command is that, when this command is executed and the concerned container does not stop automatically in 10 seconds, then docker will automatically fall back to executing `docker kill` command.

Following is a series of commands which creates and start a busybox container. Then it outputs the logs from the container. Finally, we stop the running container.

```bash
docker create busybox ping google.com
d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793

docker start d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793
d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793

docker logs d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793
PING google.com (172.217.160.238): 56 data bytes
64 bytes from 172.217.160.238: seq=0 ttl=37 time=12.531 ms
64 bytes from 172.217.160.238: seq=1 ttl=37 time=15.300 ms
64 bytes from 172.217.160.238: seq=2 ttl=37 time=18.923 ms
64 bytes from 172.217.160.238: seq=3 ttl=37 time=16.998 ms
64 bytes from 172.217.160.238: seq=4 ttl=37 time=15.382 ms
64 bytes from 172.217.160.238: seq=5 ttl=37 time=16.754 ms
64 bytes from 172.217.160.238: seq=6 ttl=37 time=15.589 ms
64 bytes from 172.217.160.238: seq=7 ttl=37 time=14.521 ms
64 bytes from 172.217.160.238: seq=8 ttl=37 time=13.746 ms

docker stop d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793
d506eaabd695a57e27fcec70f1f3caae1b8f5006e40f668e5c2a95388ce6c793
```

### Multi-Command Containers

As an illustration, let's start running a new container with `redis-server` running inside it. Redis is an in memory data structure store. Following is the command to do so:

```bash
docker run redis
```

#### Executing Commands in Running Containers

After starting the container using the `redis` image, we now need to somehow start-up the the `redis-cli` also inside the container. For this, we would use the `docker exec` command:

![](/files/zqVyX6YWkVvzgxSFAe1r)

Following is how to run `redis-cli` in the started container:

```bash
docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS      NAMES
b025f927bfa2   redis     "docker-entrypoint.s…"   27 minutes ago   Up 27 minutes   6379/tcp   flamboyant_sammet

docker exec -it b025f927bfa2 redis-cli
127.0.0.1:6379> set myvalue 5
OK
127.0.0.1:6379> get myvalue
"5"
```

### Command Prompt in a Container

There is another usecase for the `docker exec` command which is more commonly used. This usecase is getting shell or terminal access to a running container. In other words, this would be mean running shell commands inside of a container without running `docker exec` repeatedly.&#x20;

Following is the command for this:

```bash
docker exec -it b025f927bfa2 sh
# cd /
# ls
bin  boot  data  dev  etc  home  lib  media  mnt  
opt  proc  root  run  sbin srv   sys  tmp    usr  var
# export b=5
# echo $b
5
# redis-cli
127.0.0.1:6379> 
# exit
```

`sh` is a command processor which allows to type commands in and have them be executed inside of that container. There are other command processors as listed below:

![](/files/Ag1e8PzPg1zoreBzJZrH)

#### Starting a Shell

We can also start a shell via the `docker run` command like below:

```bash
docker run -it busybox sh
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var
/ # echo hi there
hi there
/ # exit
```

One disadvantage of starting the shell via the `docker run` command is that it does not allow to run the container's default process when starting up. In practice, generally we start the container and then use the `docker exec` command to start a shell within a container.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://amanalok.gitbook.io/mlops/docker/introduction-to-docker.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
