How-To

Introduction to Docker, Part 1: Getting Started

Docker radically changed the IT world as it was the product that popularized container technology.

Containers, unlike virtual machines (VMs), do not virtualize an entire operating system (OS); instead, they isolate each instance from one another and have their own software, libraries and configuration files. Because containers share the services of a single OS kernel, they use fewer resources than VMs. Moreover, being that they are self-contained, containers can be stored and pulled from a central repository and run on other computers.

Docker is a technology that I have been wanting to work with for a while, but I have not made time to do so until now. In this series article, I will show you how to install Docker containers on a Linux system. I will also discuss Docker images and containers, the performance hit of Docker, and how to use network and storage with containers.

By way of terminology, Docker is a set of products that allow you to set up a Platform-as-a-Service (PaaS) implementation that runs instances (containers) of an application or OS. These instances are created from images that can be created or pulled down from a central repository. I will use the terms "instance" and "container" interchangeably throughout this series of articles to describe a running image.

[Click on image for larger view.]

Installing Ubuntu
Docker is both hardware and OS agnostic. It can run on any number of OSes, including Linux, Windows and macOS. Likewise, it runs on Intel, ARM and other hardware. For these articles, I will be installing Docker on top of Ubuntu running on a Maxtang NX6412-B11, a low-cost ($300), small form-factor computer containing a quad-core Intel Celeron J6412 processor with 8GB of RAM and a 128GB SATA SSD. You can read my hands-on review of the NX6412-B11 here.

I chose Ubuntu 22.04.1 as my OS as it has long-term support (LTS) and, as such, is a likely candidate for deployment for both companies and individual users alike. The NX6412-B11 met the recommended system requirements for Ubuntu 22.04.1 LTS; it has a 2 GHz dual-core processor or better, 4 GB of system memory, and 25 GB of free hard drive space.

I booted off a USB with the Ubuntu install ISO and installed Ubuntu using its default settings without any difficulties.

Installing Docker
To install Docker, I logged in to Ubuntu, became root user, updated my apt repository, installed the other packages that I would need, added the Docker repository to my apt repository, and then added Docker to my system by entering:


    sudo bash
    apt update
    apt install apt-transport-https ca-certificates curl software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
    apt-cache policy docker-ce
    apt install docker-ce

Initial Configuration
After Docker was installed, I verified that it was running by entering:

    systemctl status docker
[Click on image for larger view.]

To verify that it could download a test image and run it, I entered:

    docker run hello-world
[Click on image for larger view.]

As shown in its output, Docker ran a "hello-world" command, pulled an amd64 image down from the Docker hub (a repository for Docker images), created a container for it and ran it. This displayed a message from the container.

Following the suggestions in the hello-world output, I downloaded and ran an Ubuntu container in an interactive mode (the -it switches) by entering:

    docker run -it ubuntu bash
[Click on image for larger view.]

The command prompt (root@cbe131435785:/#) told me I was inside the Ubuntu instance and not on the host OS.

Due to the fact that the container is a bare-bones Ubuntu installation, I found that when I tried to run some common commands, they were not available, but it did display the same kernel (5.15.0-53-generic) as the machine that the instance was running on.

[Click on image for larger view.]

Basic Docker Commands
So far, I have only run the docker run <image> command, which downloaded a Docker image and instantiated (started) it. Docker has a rich set of commands to help manage the containers. Toward the end of this article are a few examples of commands I used to gain more insight into the Docker system.

I opened another SSH connection to the host on which Docker was running and listed the images that had been download by entering:

    docker image ls
[Click on image for larger view.]

This showed the two images that I had downloaded (note the extremely small size of the Ubuntu image).

To see which containers were running, I entered:

    docker ps
[Click on image for larger view.]

By adding the "-a" switch to the command, I could see the status of all the containers.

[Click on image for larger view.]

The "Up" status of the Ubuntu image indicated that it was still running in the background, while the "Exited" status of hello-world showed that it was no longer actively running.

When I reentered docker run hello-world, and entered ps -a, it showed two hello-world containers, each with a unique container ID.

[Click on image for larger view.]

To stop my Ubuntu image, I entered:

    docker stop cbe131435785
[Click on image for larger view.]

To restart the Ubuntu image, I entered docker start cbe131435785.

[Click on image for larger view.]

At this point, the container was running, but I had lost the access I had when I originally started it with the "-it" command. To get an interactive prompt to the container, I entered:

    docker exec -it cbe131435785 /bin/sh
[Click on image for larger view.]

This allowed me to interact with the bash shell of the container. From this prompt, I could see my hostname, which was different than that of my host OS.

To stop the container, I entered:

    docker stop  cbe131435785
[Click on image for larger view.]

So far, I have used the container ID here to manage the container, but you can use the "-name" switch to give it a friendly name when you instantiate it. To demonstrate this, I started two different containers, each running a different Linux distribution (Ubuntu and Alpine) in the background (-d switch) with one using a name and the other without by entering:


    docker run -itd --name=DocUbuntu ubuntu
    docker run -itd alpine
[Click on image for larger view.]

The ps command showed that one container had an assigned name (DocUbuntu) and the other had an auto-assigned name (angry_ganguly).

I entered the following commands to execute a command in the containers that showed the distribution of the two container Linux distributions and then the host OS:

  
    docker exec DocUbuntu cat /etc/*-release | grep PRETTY
    docker exec angry_ganguly cat /etc/*-release | grep PRETTY
    cat /etc/*-release | grep PRETTY
  
[Click on image for larger view.]

To stop all my running containers and delete them from my system, I entered:

  
    docker ps -a
    docker stopl $(docker ps -aq )
    docker ps -a
    docker container rm -f $(docker ps -aq)
    docker ps -a
  
[Click on image for larger view.]

Conclusion
Here is a summary list of Docker commands used in this article:

Command

Notes

docker run hello-world

Download the Docker image (hello-world) from the public repository if needed and run it

docker run -it ubuntu bash

Open a shell inside the container (-it)

docker run -itd --name=DocUbuntu ubuntu

Run the container in the background (-d) with a given name (DocUbuntu)

docker image ls

List the images on the local system

docker ps

List the running containers

docker ps -a

Show all running and stopped containers (-a)

docker stop cbe131435785

Stop the container specified

docker start cbe131435785

Start the container specified

docker exec -it cbe131435785 /bin/sh

Run a command (/bin/sh) in the container specified

In this article, I walked you through how I installed Docker on top of Ubuntu. I also showed you how I downloaded and ran two different Linux distributions in containers and did basic commands to start, stop and run containers in interactive mode, as well as run a single command in a container.

It was interesting to run Linux in a container, but containers prove even more powerful in their ability to run applications. In my next articles in this series on containers, I will look at the ephemeral nature of containers and the resources that they use, explain how to use a container with networking and persistent storage, and how to run a containerized application.

Update: The second article is now live.

Featured

Subscribe on YouTube