What Is Docker Used For

Docker divides a running Linux system into small containers, each a sealed environment with its programs and everything it needs to run those programs. A container is isolated from everything else. These containers are designed to be portable so they can be shipped from one place to another, and Docker does the work of getting these containers to and from your systems.

Building Containers

Docker also builds these containers for you, and it has a social platform named Hub to help you find and share containers with others who may have already done similar work that you can build on. Docker is not the same as virtual machines. There’s only a single operating system running. That operating system is just divided up into isolated little spaces. A container is a self-contained, sealed unit of software. It has everything in it that is needed to run that code. Self-contained means batteries are included, the operating system is included, and configurations are included. It has all of the code and contains all the processes within that container. Docker has all of the networking to allow these containers to talk to the other containers they’re supposed to be able to talk to and nothing else. It has all your system’s dependencies bundled up in that container.

Linux Powers Docker

Containers include just enough of the operating system to run your code. So the way it works, it takes all the services that make up a Linux server. Networking, storage, code, interprocess communication, the whole works, and it makes a copy in the Linux Kernel for each container. So each container has its little world that it can’t see out of, and other containers can’t see. You might have one container on a system running Ubuntu serving a database through a virtual network to another container running Red Hat Linux, running a web server that talks to that database, and that web server might also be talking to a caching server that runs in a SUSE Linux based container. The vital part of understanding is that it doesn’t matter which Linux each container runs on. It just has to be Linux. And Docker is the program that manages all of this. Sets it up, monitors it, and tears it down when it’s no longer needed. Docker is a client program named Docker. It’s a command you type at the terminal. It’s also a server program that listens for messages from that command and manages a Linux system. Docker has a program that builds containers from code. It takes your code and its dependencies, bundles it up, and then seals it into a container. And it’s a service that distributes these containers across the internet and makes it so you can find other’s work and the right people can see your work. It is also a company that makes all of these.

Docker’s primary job is managing a Linux server and starting and stopping your containers as required. Most of us don’t work on laptops running Linux all the time, so many people use a virtual machine running on their laptops to act as the Linux server and run the server side of Docker. Docker provides tools that make managing this very transparent. First, we start with your computer to look at how that works. This is the thing you’re physically typing on. In your terminal, you interact with a program named Docker. That Docker is the client connecting to a program called Docker, the server that controls a Linux virtual machine. So also on your laptop, you also have a Linux Virtual Machine managed by Docker for Windows or Docker for Mac, depending on your platform. Once installed, you can click on the little whale and see it’s running. Let’s take a look at Docker in action. The example below shows how to run the most simple of docker containers. It is an example of the hello-world container provided by Docker to help explain how Docker works.

Hello Docker

% docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete 
Digest: sha256:e18f0a777aefabe047a671ab3ec3eed05414477c951ab1a6f352a06974245fe7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Docker Desktop

There have been many iterations of the Docker desktop experience, starting with boot2docker and proceeding to the modern application named Docker Desktop. Docker Desktop has made massive strides with ease of use and for managing containers, images, volumes, and development environments. Whether you are running Apple, Windows, or Linux, you can get the most up-to-date version of Docker Desktop right over at https://www.docker.com/products/docker-desktop/

We can see the result of running Docker from the command line even in our instance of Docker Desktop. We can see that the container was assigned a funny name, the image is listed, and its status shows as Exited. When a container is created using Docker, Docker provides a way to name the container using the –name flag. However, if no name is provided by the user while creating/running a Docker container, Docker automatically assigns the container a name. If you look at them carefully, you can see a pattern appear. The first name is an adjective, while the second name is the surname of a renowned scientist or hacker.

From Images To Containers In Docker

Now that we’ve got Docker installed and talked a bit about what Docker is let’s talk about what Docker does. The Docker flow is the fundamental concept. In Docker, it all begins with an image. An image is every file that makes up just enough of the operating system to do what you need to do. Traditionally you’d install a whole operating system with everything for each application you do. With Docker, you pair it way down so that you have a little container with just enough of the operating system to do what you need to do, and you can have lots and lots of these efficiently on a computer. Let’s take a look at that. So let’s take a look at Docker images. The command to look into your Docker images is Docker images.

% docker images
REPOSITORY                   TAG            IMAGE ID       CREATED         SIZE
sail-8.1/app                 latest         8030ef1081ca   2 months ago    716MB
selenium/standalone-chrome   latest         812317d6b5b4   2 months ago    1.21GB
redis                        alpine         09ae745dd677   3 months ago    28.2MB
mysql/mysql-server           8.0            e588e8734686   3 months ago    471MB
getmeili/meilisearch         latest         6d883fcc9f57   3 months ago    143MB
mysql                        5.7            efa50097efbd   4 months ago    462MB
wordpress                    latest         4ed0dea9fe0c   4 months ago    557MB
<none>                       <none>         7d72e39f09bb   7 months ago    1.09GB
selenium/standalone-chrome   <none>         66e5439a061b   7 months ago    1.19GB
redis                        <none>         50bbab999a87   7 months ago    32.4MB
hello-world                  latest         46331d942d63   7 months ago    9.14kB
getmeili/meilisearch         <none>         5201c29d69bf   7 months ago    63.5MB
docker/getting-started       latest         adfdb308d623   9 months ago    27.4MB
mysql/mysql-server           <none>         434c35b82b08   9 months ago    417MB
laravelsail/php81-composer   latest         b43378ff1fca   11 months ago   493MB
mariadb                      10.6.4-focal   6819e5d163d1   12 months ago   393MB
mariadb                      10.5.8         dd3ab601101c   21 months ago   392MB
mailhog/mailhog              latest         4de68494cd0d   2 years ago     392MB

The repository for the image is where it came from. The tag is the version of the image. And then there’s image ID, the internal Docker representation of this image. So you could always refer to an image by the combination of its name and tag in any Docker command, or you can refer to it by its number. It’s helpful to refer to them by number because sometimes they don’t have a name. But if they have a name, it’s a little more convenient to use.

The Docker run command takes an image and turns it into a running container with a process that’s doing something useful. So let’s look at running an image to make a container. So now that we’ve got an image, we want to run something in it to use the Docker run command. The first hello-world docker example showed us what to try next to see how else we can use Docker.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Let’s try that out and see what happens.

% docker run -it ubuntu bash
root@9e0e32005829:/# ls
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@9e0e32005829:/# 

The -it stands for the interactive terminal. It just causes it to have an entire terminal within the image so that you can run the shell and get things like tab completion and formatting to work correctly. This is a handy flag when you’re running commands by typing on a keyboard inside an image. You don’t need -it for interactive terminal most of the other times. As soon as the command runs, we are in the image as the root user. If we explore with the ls command, we can see we are in an ubuntu environment. Let’s look at the standard place to see what distribution we are using.

root@9e0e32005829:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"
root@9e0e32005829:/# 

We are using Ubuntu 22.04.1 LTS in this example. To exit this, you can type exit or press control D. So now we have a running image. Let’s bring up another terminal to look at it from the second terminal. We can use the Docker PS command in the new terminal to look at the running images.

% docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
e20d065c13b0   ubuntu    "bash"    3 minutes ago   Up 3 minutes             thirsty_wu

From the output, we can see our container, the running container, has an ID different from the image ID that Docker used to run it. These are not the same thing. Images have one set of IDs. Containers have their own sets of IDs. They don’t overlap, and there’s no place in Docker where you can interchange image and container IDs. We also see the image it was made from, the command running in it and when it was created, its status, and its name. Since we didn’t specify a name when we started this container, Docker helpfully made me a nice creative one of thirsty_wu. So this next part is the important idea of what makes Docker different from virtual machines or running things on a real computer. When you’re inside a container, you start from an image that is fixed. It doesn’t change. We don’t change the image when we make a container from an image. You can create multiple containers from the same image. A Docker image executes code in a Docker container. You add a writable layer of core functionalities on a Docker image to create a running container. Think of a Docker container as a running image instance. You can create many containers from the same image, each with its unique data and state. You can put files into containers, but that doesn’t put them back into the image from which the container came. They stay in that container.