Containerization
A brief overview of containerization, using the tool Docker.
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:
- Downloading Docker
- Basic Docker Commands
- Docker Storage
- Networking
- Docker Port Mapping
- Pre-Built Images
Downloading Docker
-
On Windows:
- Download the Docker Desktop application from Docker.com.
- Run the installer file - enable the WSL 2 option, if prompted.
- Launch Docker Desktop.
-
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"
-
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:
- The default bridge network for isolated communication on a single host
- The host network for direct access to the host's network stack
- 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