Docker - An Overview at High-Level
Tags: docker, beginners, devops
Published: 2022-02-19 17:17:16

# What is Docker ?

Docker is an open-source platform for building distributed software using “containerization."

Docker allows you to decouple the application/software from the underlying infrastructure into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime.

![docker](https://user-images.githubusercontent.com/83613651/154561459-bf77a2b2-8fb6-45f0-b6ba-a36f330450d0.png)


## Why Docker ?

* Docker containers are minimalistic and enable portability. 
    * Docker lets applications and their environments be kept clean and minimal by isolating them, which allows for more granular control and greater portability.

* Docker containers enable composability. 
    * Containers make it easier for developers to compose the building blocks of an application into a modular unit with easily interchangeable parts, which can speed up development cycles, feature releases, and bug fixes.

* Docker containers ease orchestration and scaling.
    * Because containers are lightweight, developers can launch lots of them for better scaling of services. These clusters of containers do then need to be orchestrated, which is where Kubernetes typically comes in.

## What is Virtualization?

Virtualization is the process of creating virtual enviroment or virtual machine by spliting one system into many different sections which act like separate, distinct individual systems. A software called Hypervisor makes this kind of splitting possible.

## What is Containerization ?

Containerization is a form of virtualization through which applications are run in containers (isolated user spaces) all using a shared OS. It packs or encapsulates software code and all its dependencies for it to run in a consistent and uniform manner on any infrastructure.

## Virtual Machine vs Docker ?

Virtual Machines (VMs) virtualize the underlying hardware. They run on physical hardware via an intermediation layer known as a hypervisor. They require additional resources are required to scale-up VMs.

They are more suitable for monolithic applications. Whereas, Docker is operating system level virtualization. Docker containers userspace on top the of host kernel, making them lightweight and fast. Up-scaling is simpler, just need to create another container from an image.

|Virtual Machine |Containers|
|:------|:-------|
|A virtualization technique where each VM has an individual operating system. |A virtualization technique where all containers share a host operating system.|
|Virtual machines are isolated at the hardware level |Each container is isolated at the operating system level.|
|Virtual machines take time to create |Containers are created fast|
|Increased management overhead |Decreased management overhead as only one host operating system needs to be cared for.|

|![vm](https://user-images.githubusercontent.com/83613651/154561595-2fa6b184-fa00-466b-8ade-5fa5e92b16d8.png) |![vm2](https://user-images.githubusercontent.com/83613651/154561657-effc4491-cac7-457c-8c74-789644c6e61e.png)|
|-----|-----|
|VM |Docker |


## What is Hypervisor?

A hypervisor is a software that makes virtualization possible. It is also called Virtual Machine Monitor. It divides the host system and allocates the resources to each divided virtual environment.  

## What are Docker Images?

A Docker image is an executable file, that creates a Docker container. An image is built from the executable version of an application together with its dependencies and configurations. Running instance of an image is a container.

Docker image includes system libraries, tools, and other files and dependencies for the application. An image is made up of multiple layers.

## What is Docker Hub?
Docker images create docker containers. There has to be a registry where these docker images live. This registry is Docker Hub. Users can pick up images from Docker Hub and use them to create customized images and containers. Currently, the Docker Hub is the world’s largest public repository of image containers.

## Components of Docker Architecture.
The four major components of Docker are daemon, Client, Host, and Registry

* **Docker daemon**: It is also referred to as ‘dockerd’ and it accepts Docker API requests and manages Docker objects such as images, containers, networks, and volumes. It can also communicate with other daemons to manage Docker services.
* **Docker Client**: It is the predominant way that enables Docker users to interact with Docker. It sends the docker commands to docker, which actually executes them using Docker API. The Docker client can communicate with more than one daemon.
* **Docker Registry**: It hosts the Docker images and is used to pull and push the docker images from the configured registry. Docker Hub is the public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. However, it is always recommended for organizations to use own private registry.
* **Docker Host**: It is the physical host (VM) on which Docker Daemon is running and docker images and containers are created.

![docker_components](https://user-images.githubusercontent.com/83613651/154563362-c459a9e8-8cdd-47ce-8bed-e0eb435d0500.png)


## What is Docker Engine?

Docker daemon or Docker engine represents the server. The docker daemon and the clients should be run on the same or remote host, which can communicate through command-line client binary and full RESTful API.

## What is Docker Image Registry?
* A Docker image registry, in simple terms, is an area where the docker images are stored. Instead of converting the applications to containers each and every time, a developer can directly use the images stored in the registry.
* This image registry can either be public or private and Docker hub is the most popular and famous public registry available.

## What are Dockerfiles?

Dockerfile is a text file that has instructions to build a Docker image. All commands in dockerfile could also be used from the command line to build images.

![Docker_File](https://user-images.githubusercontent.com/83613651/154561888-5234ef20-d5ae-40f1-8e99-d188b0b0bcb4.png)



Sample Dockerfile :
```
FROM ubuntu:16.04
COPY . /app
RUN make /app
CMD python /app/app.py
```
Each instruction in a dockerfile  creates one read-only layer:

![dfile](https://user-images.githubusercontent.com/83613651/154561953-abdfda04-8d67-4b26-9bf0-75124586b9a5.png)

# Docker Commands

### **Pull Command**

This command pulls an image from a docker public registry.
```
docker pull docker/whalesay
```

### **Build Command**

This command builds an image according to Dockerfile.
```
docker build [-t <name_of_image>] [-f <name_of_Dockerfile>] <path_to_Dockerfile>
```
 ![build](https://user-images.githubusercontent.com/83613651/154562015-cba053d2-d28c-4deb-b59a-60e82ba88d35.png)
 
  
### **Run Command**

This command runs an container of an image.
```
docker run --name nginx-container nginx:1.16
```
![run](https://user-images.githubusercontent.com/83613651/154562064-41238206-504a-4cd6-b188-4bbcdcfee32c.png)

### **ps Command**

This command lists the docker containers.
```
docker ps
```
 ![ps](https://user-images.githubusercontent.com/83613651/154562122-19820233-15f9-4ace-9c95-d6685a7e962a.png)

### **Stop Command**

This command stops a running container(s).
```
docker stop nginx-container
```

### **Remove Command**

This command removes a stopped container(s).
```
docker rm nginx-container
```
### **List Image Command**

This command lists the docker images.
```
docker images
```
### **Remove Image Command**

This command removes image(s).
```
docker rmi nginx
```
### **Attach Command**

This command attaches the terminal to a container running in the background (detached mode).
```
docker attach <container id or name>
```
### **Inspect Command**

This command returns details of the container in a JSON format.
```
docker inspect <container id or name>
```
### **Logs Command**

This command returns logs of the container running in the background (detached mode).
```
docker logs <container id or name>
```
### **Push Command**

This command pushes an image to your account on a docker public registry (dockerhub).

```
docker push vinothmohan/pro-postgres
```

### **Create a Docker Container**

Following command creates the docker container with the required images.
```
docker create --name <container-name> <image-name>
```
 
### **Pause Container**

Processes running inside the container is paused. Following command helps us to achieve this.
```
docker pause <container-id/name>
```
Container can’t be removed if in a paused state.

### **Unpause Container**

Unpause moves the container back to run the state. Below command helps us to do this.
```
docker unpause <container-id/name>
```
### **Start Container**

If container is in a stopped state, container is started.
```
docker start <container-id/name>
```
* **Stop Container**

Container with all its processes is stopped with below command.
```
docker stop <container-id/name>
```
To stop all the running Docker containers use the  below command
```
docker stop $(docker ps -a -q)
```
### **Restart Container**

Container along with its processes are restarted
```
docker restart <container-id/name>
```
### **Kill Container**

A container can be killed with below command
```
docker kill <container-id/name>
```
### **Destroy Container**

The entire container is discarded. It is preferred to do this when the container is in a stopped state rather than do it forcefully.
```
docker rm <container-id/name>
```
## Docker Network

![network](https://user-images.githubusercontent.com/83613651/154562168-135fa9bb-41e1-4779-a7dd-683942008707.png)

### **Bridge**
 The Bridge network assigns IPs in the range of 172.17.x.x to the containers within it. To access these containers from outside you need to map the ports of these containers to the ports on the host.
 
### **Host**
The Host network will remove any network isolation between the docker host and the containers. For instance, if you run a container on port 5000, it will be accessible on the same port on the docker host without any explicit port mapping. The only downside of this approach is that you can not use the same port twice for any container. 

### **None**
The None network keeps the container in complete isolation, i.e. they are not connected to any network or container.

* To create Network 
```
docker network create --driver driver_name network_name
```

## Types of Volume mounts in Docker.

There are three mount types available in Docker   

![dockervolume](https://user-images.githubusercontent.com/83613651/154562242-210ece9b-0b03-4db4-9e6c-db8b0cabcf35.jpg)

**Volume mounts** are the best way to persist data in Docker. Data are stored in a part of the host filesystem which is managed by Docker containers. (/var/lib/docker/volumes/ on Linux)

 -v or --volume flag and --mount flag could be used for docker swarm services and standalone containers.

To create a docker volume. For eg:

```
docker volume create my-vol 
``` 

Inspect a volume 

``` 
docker volume inspect my-vol
 ```


If we need to start a container with “my-vol”

* With -v flag
``` 
docker run -d  --name devtest -v my-vol:/app nginx:latest
``` 
Here nginx images with the latest tag are executed with using volume mount “my-vol”

* With --mount flag
```
docker run -d --name devtest --mount \ source=my-vol,target=/app nginx:latest
```

**Bind mounts** may be stored anywhere on the host system. A file or directory on the host machine is mounted into a container unlike volume mounts where a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents. Non-Docker processes on the Docker host or a Docker container can modify them at any time.

**tmpfs mounts** are stored in the host system’s memory only and are never written to the host system’s file system. When the container stops, the tmpfs mount is removed, and files won’t persist.


## Docker Compose

Docker Compose is a tool provided by Docker for defining and running multi-container applications together in an isolated environment. Either a YAML or JSON file can be used to configure all the required services like Database, Messaging Queue along with the application server. Then, with a single command, we can create and start all the services from the configuration file.

It comes handy to reproduce the entire application along with its services in various environments like development, testing, staging and most importantly in CI as well.

Typically the configuration file is named as docker-compose.yml. Below is a sample file:
```
version: '3'
services:
  app:
    image: appName:latest
    build: .
    ports:          
    - "8080"   
    depends_on:
      - oracledb
    restart: on-failure:10    
  oracledb:
    image: db:latest 
    volumes:
      - /opt/oracle/oradata
    ports:       
      - "1521"
```
```
docker-compose up
```
![dcompoe](https://user-images.githubusercontent.com/83613651/154562314-e9ed5bae-0654-4043-8d32-1ba4862ceaf7.png)