Docker Beginner to Advanced

What is Docker?

Docker is a software platform that allows you to build, test, and deploy applications quickly. Docker packages software into standardized units called containers that have everything the software needs to run including libraries, system tools, code, and runtime. Using Docker, you can quickly deploy and scale applications into any environment and know your code will run

What is Containers?

A container is a lightweight, isolated environment that packages an application and its dependencies, allowing it to run consistently and reliably across different computing environments. Containers provide a standardized and portable way to deploy software, ensuring that it works consistently regardless of the underlying infrastructure.

Containers use technologies like Docker that leverage operating system-level virtualization. Unlike traditional virtual machines (VMs), which emulate an entire operating system, containers share the host system's kernel and include only the necessary components to run the application. This makes containers lightweight, allowing them to start quickly and use fewer resources, resulting in better performance compared to VMs.

Virtual Machine (VM) vs Container

Virtual Machines and containers are two different technologies, each managing resources and isolation in its own way.

Virtual Machines (VM)

A virtual machine (VM) is a software emulation of a physical computer system. It runs an entire operating system and applications on top of a hypervisor or virtualization software.

VMs provide hardware-level virtualization, allowing multiple VMs to operate on a single physical host. Each VM has its own isolated instance of the operating system, CPU, memory, disk, and network interfaces.

VM isolation is strong, as VMs emulate separate hardware environments, making them suitable for running different operating systems or legacy applications with specific dependencies. However, VMs have larger resource footprints due to the need for a complete operating system for each instance, and they typically take longer to start and stop compared to containers.

Containers

Containers, on the other hand, are lightweight, isolated environments that share the host system's kernel and run as separate processes.

They use operating system-level virtualization to package applications along with their dependencies and configurations into a single, portable unit.

Containers are more lightweight compared to VMs because they do not need to emulate a full operating system. They share the host system's OS kernel, which results in faster startup times and lower resource use. Because of their lightweight nature, containers can run in higher numbers on the same host, making efficient use of resources.

Containers are ideal for running modern, microservices-based applications, promoting scalability, agility, and reproducibility by providing a standardized and portable environment. Although containers offer less isolation compared to VMs since they share the host system's kernel, they use mechanisms like namespaces and control groups to ensure process-level isolation and resource management.

Important concept of Docker

Containerization: Docker utilizes containerization technology to create and run containers. A container is a standalone executable unit that includes everything needed to run an application, such as code, runtime, libraries, and dependencies. Docker containers are based on the Docker image format, which is a lightweight, read-only template that contains all the instructions for creating a container.

Docker Engine: Docker Engine is the core component of Docker that runs and manages containers. It provides an environment to build, run, and manage containers, including features like container orchestration, resource management, networking, and storage.

Docker image: A lightweight, standalone, and executable package that includes everything needed to run a piece of software, including the code, runtime, libraries and systems tools.

Docker file: A Docker file is a text-based script that defines the steps to build a Docker image. It specifies the base image, required dependencies, configuration settings, and other instructions necessary to create a container. Docker files allow developers to automate the containerization process and ensure reproducibility.

Docker Hub: Docker Hub is a cloud-based registry that hosts a wide range of Docker images. It serves as a central repository where users can discover, download, and share Docker images. Docker Hub provides both official images maintained by Docker as well as user contributed images.

Docker Compose: Docker Compose is a tool that simplifies the orchestration of multi-container applications. It allows developers to define and manage the configuration of multiple interconnected containers as a single unit. Docker Compose files specify the services, networks, and volumes required for the application, enabling easy deployment and scaling of complex applications.

Docker solves problems

Consistent Environment: Docker provides consistent environments across development, testing, and production by encapsulating the application and its dependencies into a container.

Dependency Management: Docker containers package an application along with all its dependencies, ensuring that the application runs the same way regardless of where it is deployed

Portability: Containers can run on any system with docker installed, irrespective of the underlying infrastructure or cloud provider

Scalability: Docker empowers developers to create or destroy several instances of the application in response to user demands.

Security: Docker provides isolation at the process level, reducing the attack surface and enabling better security controls.

Isolation: Docker containers provide process isolation, ensuring that each application runs in its own isolated environment

Docker Container Lifecycle Management

The lifecycle of a docker container consists of five states:

Created state

Running state

Paused state

unpaused state

Stopped state

Killed/Deleted state

Created state

In the created state, a docker container is created from a docker image

Running state

In the running state, the docker container starts executing the commands mentioned in the image. To run a docker container, use the docker run command.

Paused state

In the paused state, the current executing command in the docker container is paused. Use the docker pause command to pause a running container.

Note: docker pause pauses all the processes in the container. It sends the SIGSTOP signal to pause the processes in the container.

Unpaused state

In the unpaused state, the paused container resumes executing the commands once it is unpaused.Use the docker unpause command to resume a paused container.Then, Docker sends the SIGCONT signal to resume the process.

Stopped state

In the stopped state, the container’s main process is shutdown gracefully. Docker sends SIGTERM for graceful shutdown, and if needed, SIGKILL, to kill the container’s main process. Use the docker stop command to stop a container.

Killed/Deleted state

In the killed state, the container’s main processes are shutdown abruptly. Docker sends a SIGKILL signal to kill the container’s main process

Difference between Docker Create, Docker Start and Docker Run:

Docker create command creates a new container from the specified image. However, it will not run the container immediately. Docker start command is used to start any stopped container. If we used the docker to create a command to create a container, then we can start it with this command. Docker run command is a combination of creating and start as it creates a new container and starts it immediately. In fact, the docker run command can even pull an image from Docker Hub if it doesn’t find the mentioned image on your system.

Difference Between Docker Pause and Docker Stop container

The docker pause command suspends all processes in the specified containers. Traditionally, when suspending a process the SIGSTOP signal is used, which is observable by the process being suspended. Also, the memory portion would be there while the container is paused and again the memory is used when the container is resumed. When we use the docker stop command, the main process inside the container receives SIGTERM signal, and after some time, SIGKILL. Also, it will release the memory used after the container is stopped. SIGTERM is the signal of termination. The intention is to kill the process, gracefully or not, but to first allow it a chance to clean up. SIGKILL is the kill signal. The only behavior is to kill the process, immediately. SIGSTOP is the pause signal. The only behavior is to pause the process. The shell uses pausing (and its counterpart, resuming via SIGCONT) to implement job control.

Docker Architecture

Docker Client

This is an application which is part of the docker engine which is responsible for accepting docker commands from the user and passing it to docker daemon.

Docker Host

The machine on which docker is installed is called docker host. It can be Windows, Linux or Mac.

Docker Daemon

This is the background process which is also part of the docker engine. Responsibility of docker daemon is to accept the commands from the docker client and perform necessary action.

Docker Registry

The place where we store docker images is docker registry. These are two types:

1) Public Docker Registry.

2) Private Docker Registry.

Public docker Registry is the hub.docker.com images uploaded here will be accessed by anyone. Private docker registry is private to a particular organization or particular team. Only they can access the images in these registries.

Architecture Steps

Step1: When we execute the command from the docker client (i.e. docker pull nginx).This command will be listened to by docker daemon.

Step2: Docker daemon will be connecting to the docker registry and find the Nginx images in docker registry & perform action.

Step3: Now this Docker daemon will be downloading nginx image from docker registry.

Step 4: In docker client we have to executed a command to run a container (docker run–name=app-d-p 8080:8080 nginx) that will be listened to by docker daemon.

Step 5: Docker daemon will check nginx image is available or not in docker host if image available it will not go to the docker Registry.

Step 6: docker daemon will take downloaded image and run the application

How to install docker on ubuntu Machine

Execute below command one by one

# Add Docker's official GPG key:

sudo apt-get update

sudo apt-get install ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:

echo \

"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] download.docker.com/linux/ubuntu \

$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \

sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

# Verify that the Docker Engine installation is successful by running the hello-world image.

sudo docker run hello-world

Note: Follow Official documentation to install docker on different OS machine

https://docs.docker.com/engine/install/

Docker File Instruction

A Docker file is a text file that contains a set of instructions used to build a Docker image. It provides a declarative and reproducible way to define the environment and configuration of a containerized application. With a Docker file, you can automate the process of building images and ensure consistent setups across different environments. A typical Docker file consists of a series of instructions that are executed in order to build the image layer by layer. It is always named Dockerfile.

FROM

RUN

CMD

ENTRYPOINT

ENV

ARG

WORKDIR

EXPOSE

VOLUME

USER

LABEL

MAINTAINER

COPY

ADD

FROM: Defines a base image, it can be pulled from docker hub
(for example- if we want to create a javascript application with node as backend then we need to have node as a base image, so it can run node application.)

Syntax:

FROM java:1.8

FROM mysql:8.5

FROM tomcat:9.5

FROM python:1.2

RUN: RUN instructions will execute while creating docker image

Syntax:

RUN yum install git

RUN yum install maven

RUN git clone <repo-url>

RUN cd <repo-name>

RUN mvn clean package

CMD: CMD instructions will execute while creating docker container Using CMD command we can run our application in container.

Syntax:

CMD sudo start tomcat

CMD java -jar <jar-file>

Note: We can write multiple CMD instructions but docker engine will process only last CMD instruction.

ENTRYPOINT: It is used to execute instructions while creating container

Syntax:

ENTRYPOINT [ "echo" , "Container Created Successfully" ]

ENTRYPOINT [ "java", "-jar", "target/springboot.jar" ]

ENV: Sets environment variables inside the image

Syntax:

ENV java /etc/softwares/jdk

ARG: By using ARG we can take dynamic values from CLI It is used to remove hard coded values in Docker file

Syntax:

ARG branch

RUN git clone -b $branch <repo-url>

$ docker build -t <imagename> --build-arg branch=master.

WORKDIR: It is used to specify working directory for image and container

Syntax:

WORKDIR /app/usr/

EXPOSE: It is used to specify on which port number our docker container will run (It is only used for documentation)

Syntax:

EXPOSE 8080

VOLUME: It defines which directory in an image should be treated as a volume. The volume will be given a random name which can be found using docker inspect command.

USER: It is used to specify username for creating image / container.

Syntax:

USER dockeruser

LABEL: It is used to add METADATA to docker objects in key-value format

Syntax:

LABEL name="icici_image"

MAINTAINER: It is used to specify docker file author information

Syntax:

MAINTAINER Harshal harshalmore.it@gmail.com

COPY: It is used to copy the files from source to destination while creating docker image

Syntax:

COPY <Source> <Destination>

Ex: COPY target/sb-api.war /app/tomcat/webapps/sb-api.war

ADD: It is used to copy the files from source to destination while creating docker image

Syntax:

ADD <Source> <Destination>

ADD <HTTP-URL> <DESTINATION>

Ex: ADD <url> /app/tomcat/webapps/sb-api.war

Sample Docker file for simple java application

# Use an official OpenJDK runtime as a parent image

FROM openjdk:11-jre-slim

Set the working directory in the container

WORKDIR /usr/src/app

# Copy the executable JAR file to the working directory

COPY target/myapp.jar .

# Make port 8080 available to the world outside this container

EXPOSE 8080

# Define the command to run the application

CMD ["java", "-jar", "myapp.jar"]