# Docker: The Docker Engine

# What happend during a container creation?

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740515684510/0825badb-968e-4a39-aaac-64ff4df32f35.png align="center")

Assuming we are creating a container using command below:

```bash
docker run --name=nginx -d nginx
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
04dfa0a3257e   nginx     "/docker-entrypoint.…"   5 minutes ago   Up 5 minutes   80/tcp    nginx
```

Let’s break down the process:

* The Docker client converts the command into API requests and sends it to the API exposed by the **daemon**.
    
* The **daemon** can expose the API on a local socket or over the network. On Linux, the local socket is `/var/run/docker.sock` and on Windows it’s `\pipe\docker_engine`.
    
* The **daemon** receives the request, interprets it as a request to create a new container, and passes it to **containerd**. Remember that the **daemon** no longer contains any code to create containers.
    
* The **daemon** communicates with **containerd** via a CRUD-style API over gRPC.
    
* Despite its name, even **containerd** cannot create containers. It converts the required Docker image into an OCI bundle and tells **runc** to use this to create a new container.
    
* **runc** interfaces with the OS kernel to pull together all the constructs necessary to create a container (namespaces, cgroups, etc.). The container starts as a child process of **runc**, and as soon as the container starts, **runc** exits, a **shim** process becomes the container’s parent process then.
    

# What is `shim` ?

In Docker, a **shim** acts as a lightweight process between **containerd** and the **container** itself. It enables daemonless containers, which allows the Docker daemon to be updated or restarted without affecting running containers. The **shim** forks a **runc** process to start the container but remains as the container’s parent process. It handles low-level tasks like managing STDIN/STDOUT streams and reporting the container's status. **Shims** also offer flexibility by allowing different low-level runtimes to replace **runc**.

# How Docker is implemented on Linux

You can find these components in the `/usr/bin/` directory:

```bash
/usr/bin/dockerd (the Docker daemon) 
/usr/bin/containerd 
/usr/bin/containerd-shim-runc-v2 
/usr/bin/runc
```

Also, you can find some clue with a combination of `docker ps` and `ps -aux | grep <container_id>` command:

```bash
# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
04dfa0a3257e   nginx     "/docker-entrypoint.…"   23 minutes ago   Up 23 minutes   80/tcp    nginx

# ps -aux | grep 04dfa0a3257e
root        2734  0.0  0.3 1237848 13664 ?       Sl   15:37   0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 04dfa0a3257eeecdc2c575446e0f6634b589a7791b1706b4a95c88aa0548752f -address /run/containerd/containerd.sock
```

# Reference

Poulton, Nigel. Docker Deep Dive: Zero to Docker in a single book (English Edition) (p. 63). (Function). Kindle Edition.
