Deep dive into docker 0x1
Tags: devops, docker, microservices, containers
Published: 2020-11-07 18:27:02

## __What is docker ?__
In today's era due to the rise of the microservices need of containerizing applications also increases. Container allows us to package our application with all the libraries and binaries it's needed to run . Docker is one of popular tool which helps to build containerization applications .

![Docker](https://neilkillen.files.wordpress.com/2020/03/dockerfiletocontainer.png)

## __Docker Engine__
Docker Engine is a client-sever application with these components:

* A server with long-running program called daemon.
* A rest API which establish the communication between the client 
  and host .
* A command line interface .

![Docker Engine](https://docs.docker.com/engine/images/engine-components-flow.png) 

## __Advantages of Docker and Container :__
* efficient use of system resources.
* microservice architecture.
* Provides loose coupling .
* high performance applications.
* secure and scalable.

## __Containers and Virtual machines :__
* A container share the kernel of the host operating system which 
  makes it's lightweight. 
* Where as virtual machines have it's own kernel and runs on top 
  of the host operating system with virtual access to the host 
  operating system through a hypervisor .

[For more insights click me ....](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/containers-vs-vm)

 ![Containers and Virtual machines](https://dev-to-uploads.s3.amazonaws.com/i/4l5fmpg8xu3tsv4apkyf.png)

## __Docker Architecture :__
Docker runs in a client server architecture. The docker client talks to the docker demon and, Which does the heavy lifting of building , running and distributing the docker containers. The docker client and the demon connect using a REST Api using a unix socket or network interfaces .

 ![Docker Architecture](https://docs.docker.com/engine/images/architecture.svg)

### __The Docker daemon :__
The Docker daemon listens for Docker commands from the client(docker cli) and then manage the services, building, running the container.

### __The Docker Client :__
The Docker Client is the Docker cli you can build the images log the container and manage the docker services with this.

### __Docker registries :__
Docker registries stores the docker images(Both official and unofficial) . Docker hub is the public registry anyone can use. 
We can pull , push , the images and this is helpful if we are working on a team (Make sure that you are logged in).    

## __Docker objects :__
* Images
* Containers
* Services
* Networks
* Volumes

### __Images :__
* A docker image is a read only configuration file which holds the 
  instructions to create a container and often based on some 
  another image (Base Image) with some additional customization .
  for example if we are pulling the docker image for ubuntu and we 
  are installing nginx web server so the base image image is 
  ubuntu and on top of that we are installing nginx web server we 
  can also make our own docker image with a Dockerfile.

* suppose we want run a nginx container 
  ```$docker pull nginx```
  ```$docker build . -t nginx```
  ```$docker images```
  copy the image id of the running container .
  ```$docker run -p 8080:8080 imgid```
  To debug the container
  ```$docker exec -it imgid```

### __Dockerfile :__
Dockerfile (Make sure the 'D' is capitalized) contains a set of commands which user could run on the command line to assemble the image .

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/etmj2php88khx0mug50e.png)

 1. compress version of node.js(Base Image) 
 2. folder where to write the code 
 3. copy the file and '.' Means root \
 4. Install the packages
 5. copy the rest of the code into the root dir
 6. run the command to start the application
 7. which port to expose the container

### __Container :__
A container is a runnable instance of an image . We can start, stop, delete, remove a container using the api (docker cli). 
We can attach one or more containers using a concept called network and build another container based on its current state .
```$docker ps```
```$docker start (container id)```
```$docker stop  (container id)```
```$docker rm    (container id)```
```$docker rmi   (container id)``` 

### __Services :__
Services allows us to scale container across multiple daemons .
Which all work together as a swarm with multiple managers and workers.
![Docker Swarm](https://docs.docker.com/engine/swarm/images/swarm-diagram.png)

[For More Insights about master and worker click me ..](https://docs.docker.com/engine/swarm/how-swarm-mode-works/nodes/)

### __Network :__
Docker Network provides a isolated environment in which the communication between two containers happens .

### __Volumes :__
Docker Volumes is a data persistent used to maintain a unchangeable state inside a container . Helps from disaster recovery more specifically if there is sudden network drop or hard shut down .

# __Docker Compose :__
Docker compose is a configuration file for defining multi-container docker application . 

### __Docker-compose file :__
* Multiple isolated containers on a same host .
* Avoid repetitive command .
* Preserve volume data when container are created .
* Only created container that have changed .

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/thbxac8es756unc64bc7.png)

```$docker-compose (compose file) up``` 
```$docker-compose (compose file) down```

### __Let's take a simple example :__
* If we are not using docker compose we have to write individual command to start the containers .  

```
$docker network create mongo-network
 
<-- command for mongodb -->
mongodb
docker run -d \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=password \
--net mongo-network \
--name mongodb \
mongo

<-- command for mono-express -->

docker run -d \
-p 8081:8081 \
-e ME_CONFIG_MONGODB_ADMINUSERNAME=admin \
-e ME_CONFIG_MONGODB_ADMINPASSWORD=password \
-e ME_CONFIG_MONGODB_SERVER=mongodb \
--net mongo-network \
--name mongo-express \
mongo-express
```

```yaml
version: "3"
services:
  mongodb:
    image: mongo
    ports:
      - "27017:27017"
    environments:
      MONGO_INITDB_ROOT_USERNAME=admin    
      MONGO_INITDB_ROOT_PASSWORD=password
  mongo-express:
    image: mongo-express
    ports:
    - 8081:8081
    environments:
      ME_CONFIG_MONGODB_ADMINUSERNAME=admin    
      ME_CONFIG_MONGODB_ADMINPASSWORD=password    
      ME_CONFIG_MONGODB_SERVER=mongodb 
```

* start the container 
```$docker compose -f mongo.yml up```

* default docker network got assigned
```$docker network ls```