Docker in Practice. Part 1( Basics)

Docker in Practice. Part 1( Basics)

Introduction: What is Docker, and Why is it so Important?

In simple words, Docker is a tool that allows developers, sys-admins, etc., to easily deploy their applications in containers to run on the host operating system, i.e. Linux.

The primary advantage of Docker is that it enables developers to compile a program and all of its dependencies into a single, standardized unit for software development. It allows developers to package and distribute their applications fast, consistently, and reliably. It also makes it easy to run those applications in various environments, such as on a developer's local machine, in a testing environment, or in a production environment.
Docker also makes it easier to scale applications, as containers can be easily moved from one host to another.

What was before Docker?

Not Docker in particular, but before containers, there were operating system virtualization, chroot, and resource isolation.
OS-virtualization, which involves creating multiple virtual environments(VMs) on a single physical host. Which can run their own operating systems and applications and are isolated from each other. Operating system virtualization has been around for decades and is still in use today.
Another technology that preceded containers is chroot, which allows a user to change the root directory for a process and its children. This can be used to isolate a process and its dependencies from the rest of the system.
Overall, containers build upon these and other technologies and concepts to provide a lightweight and portable way to isolate and run applications.

Docker vs VMs

Advantages of Docker

Containers have several advantages over prior technologies, such as they are more Lightweight, Portable, and Isolated. Containers also allow developers to package and distribute applications consistently, making it easier to develop and test applications. It can be easily automated, which can save time and reduce the risk of errors when building, testing, and deploying applications.

Overall, containers offer a lightweight and efficient way to isolate and run applications, making them an attractive option for developers.

If you are already a Developer or just started with development (Frontend, Backend, Node dev, Python-dev, etc) knowledge of Containers will be incredibly beneficial to your development journey. And if you are planning to learn DevOps it is something necessary to know. This Blog on Docker will help you learn the Docker & container concepts very easily, with examples.

Prerequisites

There are no particular skills needed for this tutorial beyond a basic comfort with the UNIX command line and using a text editor. Prior experience in developing web applications will be beneficial but is not required. If you're interested in following along, please create an account on Docker Hub.

Let's do a hands-on on Docker containers.

To work with Docker, it is not necessary to know the Docker architecture or how Docker works [You can see that here.], but we need to understand some of the terms.

  1. Image: A Docker image is a lightweight, standalone, and executable package that includes everything an application needs to run, including the application code, libraries, dependencies, and runtime.

  2. Container: A Docker container is a running instance of a Docker image. A container allows an application to be run in a lightweight, isolated environment.

  3. Registry: A Docker registry is a centralized storage location for Docker images. Docker provides a free public registry called Docker Hub, which allows users to store and distribute their images.

  4. Dockerfile: A Dockerfile is a text file that contains the instructions for building a Docker image. It specifies the base image, the dependencies, and the commands needed to run the application.

Let's run the first command.

docker run hello-world

If your system is running Docker properly, you should have an output saying, "Hello from Docker!"

docker run <IMAGE_NAME> is just spinning up containers of the specified image.

You can also see the 2nd and the 3 rd lines where the docker first searches for the image locally, and if it is unable to find it, it goes and look at the DockerHub and pull the image from there.

There are many flags we can use in the docker run like --name <CONTAINER_NAME> that will give a specified name to the container, which we can use to refer to instead of the container ID; we also use the -d flag which will run the container in the background and print out the container ID.

But you might ask, Hey Debasish, what do you mean by background? Where is the information about containers running in the background? How can I access them?

Trust me, we will explore that.

docker run -d --name myNginx nginx

This command will run a container in the background with the name "myNginx". If you remove the `-d' flag, you will see that the terminal has frozen. Because the container will take over the terminal.

Now, if you run docker container ls, you can see the information about all the running containers(you can also use docker ps). Container ID, image name, status, ports, and container name.

Ok, so my Ngnix server is running, but how can I access it? Can I simply curl http://localhost:80? If you try this, you will not get any response. Now you may say, "hey Debasish though my Nginx server is running, why wouldn't I be able to use it? Or how can I access my Nginx server?"

The answer is that the container is running on our local machine, but the Nginx server we are trying to access is actually running inside the container. A container is not the server or the application we will run on the Docker but the isolated environment where our applications or servers will run. So we will be able to access the server from inside the container.

So, how can we go inside the container?

docker exec -it myNginx bash

Booom, we are inside the container, and your terminal initials will look like root@<container_id>:/#. Now you can curl http://localhost:80, and we will get the raw nginx home page as a response from the server.

Here docker exec <container_id> <command> will run the specified command inside the corresponding container, and -it is for an interactive terminal, so after opening the container's bash shell, we will stay inside. We can also run any command and open any other available shell, i.e., sh, bash etc.

There is another way to access any serving port from outside the container, and we can poke a hole into the container, publish port no inside the container, and forward it to an external port. We can do it while starting the container.

Let's stop the running container first by running.

docker container stop myNginx

Now let's start the container again while publishing container port 80 to port 8080 into our local machine.

docker run -d -p 8080:80 --name portNginx nginx

-p <host_port_no>:<container_port_no> now we can access the Nginx home page by requesting localhost:8080. It will forward the request to the container port 80 and get back the response from there.

There are also some basic commands like

  1. docker search: Search the Docker Hub for images. Use the docker search command followed by the search term.

     docker search ubuntu
    
  2. docker pull: To pull an image or a repository from a registry, use the docker pull command followed by the image or repository name.

     docker pull ubuntu:18.04
    
  3. docker stop: To stop a running container, use the docker stop command followed by the container name or ID.

    First, we start the container by docker run --name my-container ubuntu:18.04

     docker stop my-container
    
  4. docker start: To start a stopped container, use the docker start command followed by the container name or ID.

     docker start my-container
    
  5. docker rm: To remove one or more containers, use the docker rm command followed by the container name or ID.

     docker rm my-container
    

    We need to use -f to remove a running container forcefully.

  6. docker rmi : To remove one or more images, use the docker rmi command followed by the image name or ID.

     docker rmi ubuntu:18.04
    
  7. docker inspect: To display detailed information about a Docker container or image. You can specify the name or ID of the container or image as an argument.

    For example, to inspect a container called my-container, we can use the following command:

     docker inspect my-container
    

    This will display detailed information about the my-container container, including the container's ID, name, state, image, and configuration.

In part 2, we will dive deeply into Dockerfile, how to build and dockerize applications, push them to DockerHub, and learn about Docker volume and Docker networks.