# Simplifying Docker.

I know before learning or using any new technology, our first question often is why use it in the very first place.

Well, we need to understand how things were before Docker came into the picture and the problem it aimed to fix.

### Before Docker

Virtual machines (VMs) were the primary solution for many application development and deployment needs. VMs offered a way to create isolated environments within a single physical server. However, provisioning multiple virtual machines, each with its operating system, could be resource-intensive and less efficient. The virtual machines also consume higher disk space as each VM is heavy. This is the exact problem that **containers** aim to solve.

### Containers

Containers are not something new; they have existed for a long time. Think of a container as an isolated virtual environment for your application, but it's much lighter and faster than VMs. Containers use the same underlying operating system kernel, unlike VMs. A container includes your application and everything it needs to run, like code, settings, dependencies, and some parts of the OS. They run consistently across different environments, isolated from the rest of the system.

### VMs & Containers

It's not a choice between containers or virtual machines; it's often containers and virtual machines coexisting in large environments.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697916551066/aeb68f2c-a431-4684-81a6-1c331f41606c.png align="center")

Containers are the best option for modern apps due to their portability and scalability, making them perfect for cloud-native solutions. Yet, VMs are better for hosting applications, offering strong isolation by allowing different operating systems and kernels to run on a single machine. Now, you might provision a virtual machine for hundreds or thousands of containers.

### What is Docker?

Docker is a high-level tool that provides a user-friendly interface and powerful functionalities for creating, managing, and running containers. It helps in the process of setting up and working with containers, allowing users to package applications and their dependencies in a consistent, portable, and efficient manner. You don't need to spend hours setting the environment for your application. Just put your application's stuff inside a **"Docker Container"** and it's ready to run.

### Client-Server Architecture of Docker

Yes, Docker uses a Client-Server architecture. The user interacts with the Docker Client with commands. The Client communicates with the Docker Daemon, which does all the tasks such as building and running them.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697917613222/62e03e65-eef9-403c-b590-6ee78b5f649c.png align="center")

### Some Docker Elements

* **<mark>Docker Image</mark>**
    
    Docker image is a template for creating a container, it is built using the instructions that are defined in a Dockerfile. They are designed in layers and each layer is immutable, meaning they do not change after they are built. This immutability ensures consistency in different environments.
    
* **<mark>Docker registries</mark>**
    
    Docker registries are the centralized repo for Docker Images. One can choose between private or public (Docker Hub) registries according to your needs. Docker images are pushed to and pulled from these registries, allowing for easy distribution and sharing of containerized applications.
    
* **<mark>Dockerfile</mark>**
    
    Dockerfile is like a blueprint for building a house. This file contains all the instructions and configuration to create an Image. It defines the instructions like base image, sets up the environment, installs software, copies files, and specifies commands to run.
    
    Here's a simple Dockerfile that prints "Hello, Docker!" when you run a container from it :
    
    ```yaml
    FROM python
    CMD ["python", "-c", "print('Hello, Docker!')"]
    ```
    

### Workflow

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1697918564254/87d94862-f3d5-4f8a-931f-3d6a7c18bac7.png align="left")

A Dockerfile serves to create Docker Images. These Docker Images are like snapshots of your application. They are lightweight and portable. Once you've built a Docker Image, you can use it to create isolated instances called containers. Containers are where your application runs.

### Some commands

```yaml
docker pull imageName # Pull an image

docker images # List Docker images

docker run -it imageName # Run a container interactively

docker run -d imageName # Run a container in detached mode (background)

docker ps -a # List all containers (including stopped ones)

docker stop containerID or ContainerName # Stop a container
 
docker start containerID or ContainerName # Start a container

docker rm containerID or ContainerName # Remove a container

docker rmi imageName  # Remove an image

docker push imageName  # Push an image to a registry 

docker logs containerID or ContainerName # View logs of a running container

docker exec -it containerID or ContainerName # Execute a command in a running container
```

### Hands-on

Let's try to pull an image from [Docker Hub](https://hub.docker.com/) which is a public registry and run a container. Make sure you've configured Docker into your system and Docker daemon is running. For assistance: [Get Docker](https://docs.docker.com/get-docker/)

* We'll be using the python image here :
    
    ```yaml
    root@MSI:~# docker pull python
    Using default tag: latest
    latest: Pulling from library/python
    0a9573503463: Pull complete
    1ccc26d841b4: Pull complete
    7c45daddd450: Pull complete
    0952bd8ba4ec: Pull complete
    53f1aa318bc2: Pull complete
    Digest: sha256:2586dd7abe015eeb6673bc66d18f0a628a997c293b41268bc981e826bc0b5a92
    Status: Downloaded newer image for python:latest
    docker.io/library/python:latest
    
    What's Next?
      View summary of image vulnerabilities and recommendations → docker scout quickview python
    ```
    
    By default docker pulls the latest version of Python, you can specify the tag implicitly. e.g. `docker pull python:3.11`
    
* Now that you have an image in your system you can create a container from it :
    
    ```yaml
    root@MSI:~# docker image ls
    REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
    python       latest    17e65561fd2c   5 days ago   1.02GB
    root@MSI:~# docker run -it python
    Python 3.12.0 (main, Apr 20 2024, 09:45:59) [GCC 12.2.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> print('Hello, world!')
    Hello, world!
    >>> (3+7)
    10
    >>>exit()
    root@MSI:~# docker run -d python
    da8371465e74e7cdc6a29578c67f4fdf973f0e9e88d723f70ceeadc4276ed416
    ```
    
    `-it` allows us to interact with the container's shell or application in an interactive and user-friendly way.
    
    `-d` runs the container in detached mode.
    
* Our purpose is achieved, so let's just remove the container and image from our system :
    
    ```yaml
    root@MSI:~# docker ps -a
    CONTAINER ID   IMAGE     COMMAND     CREATED         STATUS                     PORTS     NAMES
    da8371465e74   python    "python3"   2 minutes ago   Exited (0) 2 minutes ago             unruffled_gagarin
    root@MSI:~# docker rm da83
    da83
    root@MSI:~# docker ps -a
    CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
    root@MSI:~#
    root@MSI:~# docker image ls
    REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
    python       latest    17e65561fd2c   5 days ago   1.02GB
    root@MSI:~# docker rmi python
    Untagged: python:latest
    Untagged: python@sha256:2586dd7abe015eeb6673bc66d18f0a628a997c293b41268bc981e826bc0b5a92
    Deleted: sha256:17e65561fd2c7ecae6297c2cc049960607ff94f92f6a1ca3857f94569fc9c199
    Deleted: sha256:781e8bd079dcc84a458a8f4f3a150194c7d4d97e99f46c969a5f021443245582
    Deleted: sha256:fe26881c5fffddca7e97ebdd52578444af7a9c2b490ba91b5d793de4d8c3c984
    Deleted: sha256:75a8404e2d8b812db31af6bafa0c0cb4c8deaf763ab5134484213933def00b09
    Deleted: sha256:3a78d30473881be3a54a8b6a11de5da7ac2dd645c813dcb7331527a30e50a993
    Deleted: sha256:354f4b6949596277291588a6a2b924144fa72edbc21ff3c12e168187e233fd0d
    Deleted: sha256:2fa37f2ee66efbd308b9b91bce81c262f5e6ab6c3bf8056632afc60cc602785c
    root@MSI:~#
    root@MSI:~# docker image ls
    REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
    root@MSI:~#
    ```
    

That's it. This is all you need to know to start with Docker. Remember, there are many more advanced features in Docker, start by experimenting with containers and getting hands-on with Docker.
