Skip to content

Linux: Containers

A container is a lightweight, portable environment that that packages an application along with everything it needs to run, including applications. library, and configuration files.

The container runtime is the software responsible for running and managing those containers.

There are many runtimes to choose from:

  • runC
  • containerd
  • Docker
  • Podman

Basics

runC

runC is a lightweight command line tool that creates and runs containers directly from the command line.

containerd

It is runtime that handles the entire lifecycle of containers. Uses runC under the hood but provide high level APIs.

Docker

A popular runtime that includes everything needed to build, run, and manage containers. It uses runC and containerd under the hood.

Podman

Podman is like Docker but designed to run without a central daemon. It works the same way as Docker and most Docker commands work with Podman. Podman supports running containers as a regular user without needing root privileges.

Building an Image

FROM

FROM tells what base image to start with; which operating system and environment the container will be build on top of.

ex:

FROM python:3.11-slim 

to start with a Debian Linux that comes with Python 3.11 installed.

USER

USER defines who inside the container will run the remaining commands and processes.

ex:

RUN useradd -m appuser # to create a user

USER appuser # process subsequent command under this user

ENTRYPOINT

ENTRYPOINT defines the main command that will always run when the container starts.

ex:

ENTRYPOINT ["python", "app.py"] # to run this command every time the container starts

CMD

CMD provides default arguments to the ENTRYPOINT, or acts as the command to run if no ENTRYPOINT is set.

ex:

CMD ["--debug"] # to include a default option. So the container will run "python app.py --debug" by default

Example of Dockerfile

Dockerfile

FROM python:3.11-slim

RUN  useradd -m appuser

USER appuser

COPY app.py /home/appuser/app.py

WORKDIR /home/appuser

ENTRYPOINT ["python", "app.py"]

CMD ["--debug"]

then:

  • docker build -t myapp . to build the image
  • docker run myapp to start the container and run the app
  • docker run myapp --test to override CMD line and start the container

Image Retrieval and Maintenance

An container image contains the application code and everything needed to run it.

Image Pulling

Image pulling is the process of downloading a container image from a remote registry to local machine so it can be used to run containers. The general syntax is docker pull <IMAGE-NAME>[:TAG]. The latest tag is pull if the TAG is omitted.

ex:

docker pull ubuntu:20.04 # to pull Ubuntu image with tag 20.04

Image Tags

Tags are labels attached to container images that help identify versions or variants.

ex:

docker pull nginx:latest # to pull the latest version of nginx

Image Layers

Layers are the building blocks of container images. When pulling an image, docker pulls only images that are not previously pulled to increase efficiency.

Image Pruning

Pruning is the process of cleaning up unused containers, images, networks, and volumes to free up space.

Run:

docker system prune # to prune the system

Container Lifecycle Management

Run

docker run is used to create a new container from an image and start it immediately.

ex:

docker run -it ubuntu:20.04 bash # to create and start a Ubuntu:20.04 container with interactive bash shell

Start and Stop

docker start <CONTAINER-NAME> to start a container if it is stopped.

docker stop <CONTAINER-NAME> to stop a container if it is running.

ex:

docker start web-app # to start the container named "web-app"

docker stop web-api # to stop the container named "web-api"

Delete

docker rm is used to delete stopped container that is no longer needed. docker rm <CONTAINER-NAME or ID>

ex:

docker rm webapp-test # to permanently delete a stopped container named "webapp-test"

Prune

docker system prune is used to remove unused resources and free up space. Use -f flag to skip user prompt.

Container Inspection and Interaction

Environment Variables

They are used to pass config variables into a containers at startup. The general syntax is docker un -e <KEY>=<VALUE> <IMAGE-NAME>

ex:

docker run -e NODE_ENV=production node:18

Read Container Logs

Use docker logs <CONTAINER-NAME or ID> to see container logs.

ex:

docker logs web-api # to see the container output and error stream

Inspect Containers

Inspecting a container gives a detailed view of a container's configuration, network settings, mounted volumes, environment variables, an more. Use docker inspect <CONTAINER-NAME or ID> to inspect a container.

docker inspect web-api

Exec

exec is a command that lets users run a command directly inside a running container. The general syntax is docker exec -it <CONTAINER-NAME or ID> <COMMAND>

ex:

docker exec -it db-app bash # open bash shell in interactive mode from the db-app container

Container Storage

Mapping Container Volumes allows users to link a folder from their host machine to a folder inside the container. The general syntax is docker run -v <HOST-PATH>:<CONTAINER-PATH> <IMAGE-NAME>.

ex:

docker run -v /home/user/data:/app/data webapp

Volume Management and Operations

Create Volume

docker volume create <VOLUME-NAME>

ex:

docker volume create apidata # to create a volume named "apidata"

Map Volume

Mapping the volume connects the volume created to a specific location inside a container. docker run -v <VOLUME-NAME>:<CONTAINER-PATH> <IMAGE-NAME>

ex:

docker run -v apidata:/app/data webapi

Prune Volume

Use docker volume prune to remove unused volumes.

Network Management Operations

Create Network

A virtual network gives containers a way to interact with each other or with the outside world securely and efficiently. The general syntax is docker network create [OPTIONS] <NETWORK-NAME>.

ex:

docker network create --driver bridge apps-net # to create a bridge type network named apps-net

Port Mapping

Port Mapping allows containers to communicate with the outside world. The general syntax to map port is docker run -p <HOST-PORT>:<CONTAINER-PORT> <IMAGE-PORT>.

ex:

docker run -p 8080:80 webapp

Local Networks

Bridge Network

The bridge network is the default local network mode for Docker containers on a single host. The general syntax to create a container with a bridge network is docker run --network bridge -p <HOST-PORT>:<CONTAINER-PORT> <IMAGE-NAME>.

ex:

docker run --network bridge -p 8080:80 webapi

Host Network

The host network mode allows the container to share the host system's network stack directly. The container uses the same ip address and port as the host machine. The general syntax is docker run --network host <IMAGE-NAME>

ex:

docker run --network host webapp

none Network

The none network mode disables networking entirely for the container. Containers with this network type cannot communicate with other containers or with the outside world. They are completely isolated. The general syntax is docker run --network none <IMAGE-NAME>

ex:

docker run --network none webapi

Advanced and Overlay Networks

IPvlan

IPvlan network driver allows containers to receive IP addresses from the same subnet as the host, while still maintaining logical isolation between containers.

Macvlan

Macvlan network driver gives each container itw own MAC address and full presence on the physical network, making containers behave like independent network nodes.

Overlay

Overlay network driver is used to link containers across multiple Docker hosts, allowing them to communicate securely and seamlessly.