---
title: Containerization
author: Kirstie Martinka
description: A brief overview of containerization, using the tool Docker.
published: 2025-2-16
---

-----

# Containerization

Containerization is a method of packaging software applications and their dependencies into lightweight, portable units called containers. 
These containers run consistently across different environments, whether on a developer's machine, in testing, or in production. 

Tools like Docker and Kubernetes are commonly used for managing containers.
Docker will be used for the following instructions.

We will be covering the following topics:
1. [Downloading Docker](#downloading-docker)
1. [Basic Docker Commands](#basic-docker-commands)
1. [Docker Storage](#docker-storage)
    1. [Temporary Storage](#temporary-storage)
    1. [Volumes](#volumes)
    1. [Bind Mounts](#bind-mounts)
1. [Networking](#networking)
1. [Docker Port Mapping](#docker-port-mapping)
1. [Pre-Built Images](#pre-built-images)
    1. [Portainer](#portainer)


-----

## Downloading Docker

1. On Windows:
    - Download the Docker Desktop application from Docker.com.
    - Run the installer file - enable the WSL 2 option, if prompted.
    - Launch Docker Desktop.
1. On MacOS:
    - Download the Docker Desktop application from Docker.com.
    - Open the installer and copy the Docker application to the Applications folder.
    - Launch Docker.
    - Accept the license agreement, then select the option to "use the recommended settings."
    - Click "Finish"
1. On Linux:
    - Add the official Docker repository:

    *# sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo*
    - Install Dcoker and needed dependencies:

    *# sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin*
    - Start the Docker service:

    *# sudo systemctl start docker*
    - Enable the Docker service:

    *# sudo systemctl enable docker*
    - Allow for non-root user access (no need to use **sudo** every command):

    *# sudo usermod -aG docker $USER*
    - Logout and log back in for the changes to take effect.
    - Verify Installation:
    
    *docker --version*
    *docker run hello-world*

    If the following message is received, that means the Docker installation is working correctly:

    ```
    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.

        (amd64)

    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.
    ```

-----

## Basic Docker Commands

To pull/download an image/container: *docker pull **image***

To run an image/container: *docker run **image***
- When running a container, can also do the following:
    - *-d* to run detached
    - *id* to run the container detached
    - *-it* to start an interactive terminal (can interact with it directly)
    - *--name* to specify a name
    - *-p* for Docker port mapping (for example *-p 8080:80*)
    - *-v* to specify a volume to mount

To display active containers: *docker ps*

To display all containers: *docker ps -a*

To enter a container: *docker exec **containerID** **shell***

To stop a container: *docker stop **containerID***

To remove a container: *docker rm **containerID***

To display images: *docker images*

To remove images: *docker rmi **image***

To display volumes: *docker volume list*

To remove volumes: *docker volume rm **volume***

To create a file: *touch **/path/to/file.txt***

To display files: *touch **/path/to***

To create a new **bridge** network: *docker network create **bridge***

To connect/disconnect a container to a network: 
- *docker network connect **network** **containerID***
- *docker network disconnect **network** **containerID***

To display current networks: *docker network ls*

To display containers attached to a network: *docker network inspect **bridge***

To remove a network: *docker network rm **bridge***

-----

## Docker Storage

### Temporary Storage

Temporary storage is storage that is inside of the container. 
This only remains while the container is active - once the container is deleted, the files or folders are deleted along with it.
Temporary storage should not be used for anything in production, or that you want to keep long term.

Run a container and write a file inside of it: 

*docker run -it --name storage-test ubuntu*
*echo "Hello from Docker!" > /tmp/hello.txt*
*exit*

Verify the container has stopped:

*docker ps -a*

Start the container again:

*docker start -i storage-test*

Output the contents of the file in the specified path:

*cat /tmp/hello.txt*
**Hello from Docker!**

Exit, stop, and remove the storage-test container.

### Volumes

Volumes are storage that are self-contained and can be connected to a container. 
They are Portable, easy to backup, or share between containers.
Docker volume storage is a method for persisting data generated or used by Docker containers, allowing it to survive restarts or deletions or containers.

By default, volumes are stored outside the container's file system, typically in a specific directory on the host machine: **/var/lib/docker/volumes**

Create a volume:
- *docker volume create my-data*

Attach the volume to a container at runtime:
- *docker run -id -v my-data:/data --name volume-test ubuntu*

To access the container and run commands inside of it:
- *docker exec -it **containerNameOrID** bash*

Now in the bash shell of the container... Create a file (/data, which is where the volume is attached - will be stored in the volume, not the container itself):
- *touch /data/volume-file.txt*
- *exit*

Stop and remove the container.

### Bind Mounts

Bind mounts are storage that is a folder on your system that you want accessible from the container. 
This is usually accomplished by mapping the folder to a folder inside of the container.

-----

## Networking

Docker networking is the system that enables containers to communicate with each other, the host machine, and external networks. 
It uses different network drivers to configure how containers interact, such as:
1. The default **bridge** network for isolated communication on a single host
1. The **host** network for direct access to the host's network stack
1. The **overlay** network for multi-host container communication in distributed environments

To add containers to a network:
- *docker run -id --network my-bridge --name container-1 ubuntu*
- *docker run -id --network my-bridge --name container-2 ubuntu*

To view containers attached to a network:
- *docker network inspect my-bridge*

To connect/disconnect a container to a network:
- *docker network connect bridge container-1*
- *docker network disconnect bridge container-1*

To demonstrate communication between two containers:
- *docker exec -it container-1 bash*
- Now in the bash shell of the container...
    - *apt install -y iputils-ping*
    - *ping container-2 -c 4*

Remove the network: 
- *docker network rm my-bridge*
**Any containers connected to the network must be removed before you can delete the network.**

-----

## Docker Port Mapping

Docker port mapping is the process of connecting ports on a container to ports on the host machine, 
enabling external access to services running inside the container.

One of the most common uses of port mapping is a web server. 
HTTP (non-secure) runs on port 80. HTTPS (secure) runs on port 443. 
To run a nginx container and have the port “exposed” for users, we need to map it to a host port. 

To accomplish this, the docker run command would look like this: 
- *docker run -d -p 8080:80 nginx* 

If you need to map multiple ports to a container, you can add more -p options: 
- *docker run -d -p 8080:80 -p 1234:22 nginx*

If you don’t care what port is mapped and want Docker to choose a free host port automatically, you can use the -P flag. 
- *docker run -d -P nginx*

-----

## Pre-Built Images

Pull an image:
- *docker pull **image***

Run an image:
- *docker run -d **(any extra flags)** --name **containerName** **image**

### Portainer

*docker volume create portainer_data*
*docker run —name portainer -p 8000:8000 -p 9443:9443 -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data -d portainer/portainer-ce*

-----
##### [Return to the Beginning](#containerization)
-----