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
- Linux Powers Docker
- Hello Docker
- Docker Desktop
- From Images To Containers In Docker
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.
% 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/
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.