DevOpsยทโฑ 13 min read

What is Docker? Containers Explained for Beginners (2025)

Learn what Docker is, how containers work, Docker vs virtual machines, key commands, Dockerfile, Docker Compose, and how to containerize your first app step-by-step.

TS
TechSimpleHub Team
ยท Updated August 31, 2026
DockerContainersDevOpsKubernetesLinuxMicroservices

Docker has transformed how software is built and deployed. If you've heard phrases like "it works on my machine" or "just containerize it," you're already encountering Docker culture. This guide explains Docker from the ground up โ€” what it is, why it matters, and how to use it.

What is Docker?

Docker is an open-source platform that enables developers to package applications and all their dependencies into lightweight, portable units called containers.

A container includes everything the application needs to run: code, runtime, system tools, libraries, and settings โ€” all in one isolated package. This means the application runs identically on any machine: your laptop, a CI server, or a cloud VM.

"Docker solves the 'works on my machine' problem permanently by making your machine part of the package." โ€” Docker Community

Containers vs Virtual Machines

People often confuse containers with virtual machines (VMs). They're related but fundamentally different:

FeatureVirtual MachineContainer
OSFull OS per VM (GBs)Shares host OS kernel (MBs)
Startup timeMinutesSeconds (or milliseconds)
Resource usageHeavy (dedicated RAM/CPU)Lightweight (shared resources)
IsolationFull hardware isolationProcess-level isolation
PortabilityLimitedRun anywhere Docker runs
Use caseRunning different OSesMicroservices, app packaging

Core Docker Concepts

Docker Image

A read-only template containing instructions for creating a container. Think of it as a blueprint or a snapshot. Images are built from a Dockerfile and stored in registries like Docker Hub or Amazon ECR.

Docker Container

A running instance of a Docker image. You can run many containers from the same image, each completely isolated. Containers are ephemeral by default โ€” their filesystem is discarded when they stop (unless you use volumes).

Dockerfile

A text file with step-by-step instructions for building a Docker image. Each instruction creates a new layer in the image.

Docker Registry

A storage and distribution system for Docker images. Docker Hub is the default public registry with millions of pre-built images (nginx, postgres, node, python, etc.).

Docker Compose

A tool for defining and running multi-container applications using a YAML file. Instead of running separate docker run commands, you define all services in docker-compose.yml.

Installing Docker

Install Docker Desktop from docker.com for Mac and Windows. On Linux:

# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER   # run docker without sudo

# Verify installation
docker --version
docker run hello-world

Essential Docker Commands

Images

# Pull an image from Docker Hub
docker pull nginx
docker pull ubuntu:22.04

# List local images
docker images
docker image ls

# Remove an image
docker rmi nginx
docker image rm nginx

# Build image from Dockerfile in current directory
docker build -t myapp:1.0 .

# Tag an image
docker tag myapp:1.0 username/myapp:latest

# Push to Docker Hub
docker push username/myapp:latest

Containers

# Run a container
docker run nginx

# Run in detached mode (background)
docker run -d nginx

# Run with port mapping (host:container)
docker run -d -p 8080:80 nginx

# Run with a name
docker run -d --name my-nginx -p 8080:80 nginx

# Run interactively (bash shell)
docker run -it ubuntu:22.04 /bin/bash

# List running containers
docker ps
docker container ls

# List all containers (including stopped)
docker ps -a

# Stop a container
docker stop my-nginx

# Start a stopped container
docker start my-nginx

# Restart
docker restart my-nginx

# Remove a container
docker rm my-nginx

# Remove and stop in one command
docker rm -f my-nginx

# View container logs
docker logs my-nginx
docker logs -f my-nginx   # follow (live tail)

# Execute command in running container
docker exec -it my-nginx /bin/bash
docker exec my-nginx cat /etc/nginx/nginx.conf

Volumes (Persistent Data)

# Create a named volume
docker volume create mydata

# Mount volume in container
docker run -d -v mydata:/data nginx

# Mount host directory
docker run -d -v /home/user/config:/etc/nginx nginx

# List volumes
docker volume ls

# Remove unused volumes
docker volume prune

Writing a Dockerfile

Here's a Dockerfile for a simple Node.js app:

# Use official Node.js LTS image as base
FROM node:20-alpine

# Set working directory inside container
WORKDIR /app

# Copy package files first (cache optimization)
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application source
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Create non-root user (security best practice)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# Define start command
CMD ["node", "server.js"]

Build and Run

docker build -t my-node-app .
docker run -d -p 3000:3000 --name nodeapp my-node-app

Docker Compose

Running a web app with a database? Docker Compose makes this easy:

# docker-compose.yml
version: '3.9'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://user:pass@db:5432/mydb
    depends_on:
      - db
    volumes:
      - ./src:/app/src   # live code reload

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
# Start all services
docker compose up -d

# View logs for all services
docker compose logs -f

# Stop all services
docker compose down

# Stop and remove volumes
docker compose down -v

Docker Networking

# List networks
docker network ls

# Create a custom network
docker network create mynet

# Run containers on same network (they can talk to each other by name)
docker run -d --network mynet --name db postgres
docker run -d --network mynet --name web -p 80:80 nginx

# Inspect a container's network settings
docker inspect mycontainer | grep -A 20 NetworkSettings

Best Practices for Docker in Production

  • โœ… Use official base images and pin specific versions (not :latest)
  • โœ… Run containers as non-root users
  • โœ… Keep images small โ€” use Alpine variants, multi-stage builds
  • โœ… Use .dockerignore to exclude unnecessary files from the build context
  • โœ… Never store secrets in Dockerfiles or image layers
  • โœ… Scan images for vulnerabilities with docker scout or Snyk
  • โœ… Use health checks so orchestrators know when containers are ready

Docker vs Kubernetes

Docker runs containers. Kubernetes (K8s) orchestrates them at scale across clusters of machines. Think of it this way:

  • Docker = shipping container
  • Kubernetes = the port with cranes, scheduling, routing, and automation

Most production deployments use Docker to build images and Kubernetes to manage how those containers run, scale, and recover from failures.

Conclusion

Docker has become a fundamental skill for modern software development. Containers solve the "it works on my machine" problem permanently, make deployments reproducible, and enable microservices architectures. Start with the basics: pull an image, run a container, write a Dockerfile โ€” and the rest will follow naturally.


Related guides: Linux Handbook ยท Chmod Calculator ยท Cron Parser