Docker - Understanding the Basics
Tags: docker, programming, kubernetes, devops
Published: 2021-08-12 11:03:58

Docker is an open-source centralized platform designed to create, deploy, and run applications. It  takes away repetitive, mundane configuration tasks and is used throughout the development life-cycle for fast, easy and portable application development 
Docker uses container on the host's operating system to run applications. It allows applications to use the same Linux kernel as a system on the host computer, rather than creating a whole virtual operating system. Containers ensure that our application works in any environment like development, test, or production.

Docker Features

- Easy and Faster Configuration - It helps us to configure the system easily and faster.We can deploy our code in less time and effort.
- Increase productivity - By easing technical configuration and rapid deployment of application. No doubt it has increase productivity.
- Application Isolation - It provides containers that are used to run applications in isolation environment. Each container is independent to another and allows us to execute any kind of application.
- Swarm - It is a clustering and scheduling tool for Docker containers. Swarm uses the Docker API as its front end, which helps us to use various tools to control it. It also helps us to control a cluster of Docker hosts as a single virtual host. It's a self-organizing group of engines that is used to enable pluggable backends

- Routing Mesh - It routes the incoming requests for published ports on available nodes to an active container. This feature enables the connection even if there is no task is running on the node. 

- Services - Services is a list of tasks that lets us specify the state of the container inside a cluster. Each task represents one instance of a container that should be running and Swarm schedules them across nodes.

- Security Management - It allows us to save secrets into the swarm itself and then choose to give services access to certain secrets.

####Difference between Docker Containers and Virtual Machines
#####Docker Containers
Docker containers are the lightweight alternatives of the virtual machine. It allows developers to package up the application with all its libraries and dependencies, and ship it as a single package. The advantage of using a docker container is that you don't need to allocate any RAM and disk space for the applications. It automatically generates storage and space according to the application requirement. Also, Integration in a container is faster and cheap, does not waste of memory, and It uses the same kernel, but different distribution.

#####Virtual Machines
A virtual machine is a software that allows us to install and use other operating systems (Windows, Linux, and Debian) simultaneously on our machine. The operating system in which virtual machine runs are called virtualized operating systems. These virtualized operating systems can run programs and preforms tasks that we perform in a real operating system
However, Integration in virtual is slow and costly, wastes a lot of memory, and It uses multiple independent operating systems.

###Why Docker??
- It runs the container in seconds instead of minutes.
- It uses less memory.
- It provides lightweight virtualization.
- It does not a require full operating system to run applications.
- It uses application dependencies to reduce the risk.
- Docker allows you to use a remote repository to share your container with others.
- It provides continuous deployment and testing environment.

### Docker Container and Image
Docker container is a running instance of an image. An image is a read-only template with instructions for creating a Docker container. 
A docker image is described in text file called a Dockerfile, which has a simple, well-defined syntax. An image does not have states and never changes.
A Dockerfile is a text document that contains commands that are used to assemble an image.

##Dockerfile Instructions
The instructions are not case-sensitive but you must follow conventions which recommend to use uppercase. Docker runs instructions of Dockerfile in top to bottom order, so the first instruction should be **FROM** in order to specify the base image
A statement begin with # treated as a comment. You can use RUN, CMD, FROM, EXPOSE, ENV etc instructions in your Dockerfile.

**FROM**
This instruction is used to set the Base Image for the subsequent instructions. A valid Dockerfile must have FROM as its first instruction. ARG is the only instruction that may precede FROM in the Dockerfile. [understand how ARG and FROM interact](https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact)
```dockerfile
ARG  CODE_VERSION=latest
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
```
NB: The tag or digest values are optional. If you omit either of them, the builder assumes a latest by default.

**MAINTAINER**
Allows you to set the Author field of the generated images.
```dockerfile
MAINTAINER <name>
```

**LABEL**
We can add labels to an image to organize images of our project. We need to use LABEL instruction to set label for the image.
```dockerfile
LABEL <key>=<value> [<key>=<value> ...]
```


**RUN**
This instruction is used to execute any command of the current image.
```dockerfile
RUN <command>(shell form, the command is run in a shell)
RUN ["<executable>", "<param1>", "<param2>"] (exec form)
```

**CMD**
This is used to execute application by the image.
NB: There can be only one CMD in a Dockerfile. If we use more than one CMD, only last one will execute.

The CMD instruction has three forms:

```dockerfile
CMD ["<executable>","<param1>","<param2>"] (exec form, this is the preferred form)
CMD ["<param1>","<param2>"] (as default parameters to ENTRYPOINT)
CMD <command> <param1> <param2> (shell form)
```
**EXPOSE**
Informs Docker that the container listens on the specified network port(s) at runtime.
```dockerfile
EXPOSE <port> [<port> ...]
```

**ENV**
The ENV instruction sets the environment variable <key> to the value <value>
```dockerfile
ENV <key> <value>
ENV <key>=<value> [<key>=<value> ...]
```

**ADD**
Copies new files, directories, or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>
```dockerfile
ADD <src> [<src> ...] <dest>
ADD ["<src>", ... "<dest>"]
```

**COPY**
This instruction is used to copy new files or directories from source to the filesystem of the container at the destination.
```dockerfile
COPY <src> [<src> ...] <dest>
COPY ["<src>", ... "<dest>"] (this form is required for paths containing whitespace)
```

**ENTRYPOINT**
Allows you to configure a container that will run as an executable.
```dockerfile
ENTRYPOINT ["<executable>", "<param1>", "<param2>"] (exec form, preferred)
ENTRYPOINT <command> <param1> <param2> (shell form)
```

**VOLUME**
Creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers.
```dockerfile
VOLUME ["<path>", ...]
VOLUME <path> [<path> ...]
```

**USER**
The USER instruction sets the user name or UID to use when running the image and for any RUN, CMD and ENTRYPOINT instructions that follow it in the Dockerfile

```dockerfile
USER <username | UID>
```

**WORKDIR**
The WORKDIR is used to set the working directory for any RUN, CMD and COPY instruction that follows it in the Dockerfile. If work directory does not exist, it will be created by default.
```dockerfile
WORKDIR </path/to/workdir>
```
NB: We can use WORKDIR multiple times in a Dockerfile.

**ONBUILD**
Adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile.
```dockerfile
ONBUILD <Dockerfile INSTRUCTION>
```

**STOPSIGNAL**
The STOPSIGNAL instruction sets the system call signal that will be sent to the container to exit
```dockerfile
STOPSIGNAL <signal>
```

**HEALTHCHECK**
Tells Docker how to test a container to check that it is still working
```dockerfile
HEALTHCHECK [<options>] CMD <command> (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
```

**SHELL**
Allows the default shell used for the shell form of commands to be overridden
```dockerfile
SHELL ["<executable>", "<param1>", "<param2>"]
```