Docker Intro¶
Containers aren't lightweight VMs — that's the first lie everyone tells you and it's dangerous because it makes you think about security wrong Docker uses Linux kernel primitives — cgroups for resource limits , namespaces for isolation — to create isolated userspace environments that share the host kernel. That means a kernel exploit in your container is a kernel exploit on your host
Containers vs VMs — What Actually Matters¶
Virtual Machines: * Each VM runs its own full OS with its own kernel * Hypervisor (VMware , VirtualBox , KVM) virtualizes hardware * Guest OS has full kernel , init system , drivers * Heavy — gigabytes of disk , seconds to boot * Strong isolation boundary between VMs
Containers: * Containers share the host kernel * Docker daemon manages container lifecycle using kernel namespaces * Container has filesystem isolation but syscalls go to host kernel * Lightweight — megabytes of disk , milliseconds to boot * Weaker isolation — container escape = host compromise
Pick VMs when you need full kernel isolation (untrusted workloads , multi-tenant SaaS , training malware) Pick containers when you need density and speed (microservices , CI/CD , dev environments)
Docker Architecture — How It Actually Works¶
flowchart TB
subgraph Docker_Host[Docker Host]
Daemon[Docker Daemon - dockerd<br/>Builds images, runs containers<br/>Manages networks, volumes]
API[REST API socket<br/>/var/run/docker.sock]
CLI[Docker Client - docker CLI<br/>The thing you type commands into]
C1[Container: nginx]
C2[Container: node]
C3[Container: redis]
Daemon --> API
API --> CLI
Daemon --- C1
Daemon --- C2
Daemon --- C3
end Installing Docker¶
Never install Docker Desktop on Linux — it's a VM wrapper for macOS/Windows users who can't run Linux natively
Ubuntu/Debian:
# Remove old shitty packages
sudo apt remove docker docker-engine docker.io containerd runc
# Install dependencies
sudo apt update && sudo apt install -y ca-certificates curl gnupg
# Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up repository
echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
# Add your user to docker group (logout and back in after this)
sudo usermod -aG docker $USER
newgrp docker
Verify installation:
docker --version
docker run hello-world
Essential Docker Commands — The Survival Set¶
You don't need 200 commands. You need these:
# List running containers
docker ps
# List ALL containers (including stopped)
docker ps -a
# Run a container
docker run nginx:latest
docker run -d nginx:latest # Detached mode (background)
docker run -p 8080:80 nginx:latest # Port mapping host:container
docker run --name my-nginx nginx:latest # Give it a name
docker run -d --rm nginx:latest # Auto-remove when stopped
# Stop and remove
docker stop <container-id>
docker rm <container-id>
docker rm -f $(docker ps -aq) # Kill ALL containers (careful)
# View logs
docker logs <container-id>
docker logs -f <container-id> # Follow (tail -f style)
# Exec into running container
docker exec -it <container-id> bash
docker exec -it <container-id> sh
# Images
docker images # List images
docker pull node:20-alpine # Pull without running
docker rmi <image-id> # Remove image
Port Mapping — How Traffic Gets In¶
flowchart LR
Browser[Browser] --> Host[Host:8080]
Host -->|Docker maps port 8080| Container[Container:80<br/>nginx listening] # Map port 3000 on host to port 3000 in container
docker run -p 3000:3000 node-app
# Map multiple ports
docker run -p 8080:80 -p 443:443 nginx
# Bind to specific IP
docker run -p 127.0.0.1:8080:80 nginx
Volumes — Stop Losing Your Data¶
Containers are ephemeral — remove the container , lose the data Volumes persist data on the host filesystem
# Named volume (Docker manages location)
docker run -v mydata:/data/app ubuntu
# Bind mount (you specify path)
docker run -v /home/user/data:/data/app ubuntu
# With Node.js app for live reload in dev
docker run -v $(pwd):/app -p 3000:3000 node-app
Container Lifecycle¶
flowchart TD
Created[Created] --> Running[Running]
Running --> Stopped[Stopped]
Stopped --> Deleted[Deleted]
Created -->|docker start| Running
Stopped -->|docker start| Running docker create nginx:latest # Create but don't start
docker start <container-id> # Start stopped container
docker restart <container-id> # Stop + start
docker pause <container-id> # Freeze processes
docker unpause <container-id> # Unfreeze
docker stop <container-id> # Graceful shutdown (SIGTERM + SIGKILL)
docker kill <container-id> # Immediate shutdown (SIGKILL)
docker rm <container-id> # Delete container (must be stopped)
Prerequisites¶
Node.js section , Express section
next → devops_02_dockerfile.md