20.1.1 Container Basics Lesson
A focused guide to Container Basics Lesson, connecting core concepts with practical Docker and container operations.
The Container Basics Lesson establishes the foundational understanding of what a container is, how it relates to images, and what commands are used to create, run, manage, and remove containers. This lesson is the practical entry point to Docker — it explains the mechanics behind the most commonly used commands and gives a mental model that makes all subsequent Docker topics easier to understand.
What a Container Is
A container is a running process on the host operating system that is isolated from other processes using Linux kernel features. The isolation is provided by:
- Namespaces: Each container has its own view of the process list (PID namespace), network interfaces (network namespace), filesystem (mount namespace), hostname (UTS namespace), and IPC resources. From inside the container, it appears to have its own OS.
- Cgroups (Control Groups): Enforce limits on CPU, memory, disk I/O, and network bandwidth that the container's processes can consume.
Despite appearing like a separate machine, a container shares the host's kernel. This is the key difference between containers and virtual machines: a VM runs a full separate kernel; a container shares the host kernel but is isolated from other processes.
The Container Lifecycle
A container progresses through defined states:
- Created: The container has been created (filesystem, configuration, and metadata allocated) but the process has not started.
- Running: The container's main process is running.
- Stopped (Exited): The main process has exited. The container's writable filesystem layer, logs, and metadata still exist on the host.
- Removed: The container has been deleted. Its filesystem layer and metadata are gone.
Creating and Running a Container
The primary command to create and start a container in one step:
docker run nginx:latest
This pulls nginx:latest from Docker Hub if it is not already local, creates a container, and starts it. The terminal attaches to the container's stdout and stderr.
To run in the background (detached mode):
docker run -d nginx:latest
To give the container a name:
docker run -d --name my_web nginx:latest
To map a host port to a container port (allowing external access):
docker run -d -p 8080:80 --name my_web nginx:latest
The format is -p <host_port>:<container_port>.
Listing Containers
docker ps
Shows running containers:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp my_web
docker ps -a
Shows all containers including stopped ones.
Stopping a Running Container
docker stop my_web
Sends SIGTERM to the container's main process and waits up to 10 seconds for a graceful shutdown. After the timeout, SIGKILL is sent.
Starting a Stopped Container
A stopped container retains its configuration and writable filesystem layer. It can be started again:
docker start my_web
Restarting a Container
docker restart my_web
Equivalent to docker stop followed by docker start.
Viewing Logs
Container stdout and stderr are captured by Docker's logging driver:
docker logs my_web
To follow live output:
docker logs -f my_web
To see only the last 20 lines:
docker logs --tail 20 my_web
Running a Command Inside a Running Container
docker exec -it my_web bash
Opens a bash shell inside the running container. The -it flags provide an interactive terminal. Changes made this way affect only this container instance.
Inspecting a Container
docker inspect my_web
Returns a detailed JSON document with the container's full configuration, state, network settings, mounts, and environment variables.
Removing a Container
A container must be stopped before it can be removed:
docker stop my_web
docker rm my_web
To force-remove a running container immediately:
docker rm -f my_web
The --rm Flag
For containers that run a task and exit, use --rm to automatically remove the container when it exits:
docker run --rm alpine echo "done"
The container runs, prints "done", exits, and is immediately removed. This is the standard pattern for one-off containers.
Container Isolation Experiment
To understand container isolation, run two separate Alpine containers and observe that they have independent process lists and filesystems:
docker run -it --name container_a alpine sh
In a second terminal:
docker run -it --name container_b alpine sh
Inside container_a, any files created are invisible to container_b. Any processes started in container_a are invisible to container_b. Both containers share the host kernel but are isolated from each other.
Container vs. Virtual Machine
| Container | Virtual Machine | |
|---|---|---|
| Kernel | Shared with host | Separate kernel |
| Startup time | Milliseconds | Seconds to minutes |
| Disk footprint | MBs | GBs |
| Isolation | Namespace and cgroup | Hardware virtualization |
| Portability | Very high | Moderate |
Containers are lighter and faster than VMs because they do not need to boot a full OS. The tradeoff is weaker isolation: a kernel vulnerability affects all containers on the host simultaneously.