Skip to content

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