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 imagedocker run myapp
to start the container and run the appdocker run myapp --test
to overrideCMD
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.