Docker for Beginners: Containers Explained Without the Jargon
β‘ Quick Answer
Docker tutorial for beginners β learn containers vs VMs, Docker images, Dockerfiles, docker-compose, and how to containerize a real web application step by step.
Get more content like this on Telegram!
Daily AI tips, notes & resources β free
Advertisement
Docker for Beginners: Containers Explained Without the Jargon
Docker is a platform for running applications inside containers β isolated, lightweight environments that bundle your app with its exact dependencies. Think of a container like a shipping container: whatever is packed inside arrives identical no matter which ship, truck, or port it passes through.
That solves one of the most annoying problems in software development: "it works on my machine." A Node.js project that takes three hours to configure by hand β wrong Node version, wrong npm version, PostgreSQL installed differently than the docs expect β runs in minutes once it's containerized, because the container carries its own environment with it.
This guide starts from zero: what containers are, how to build your first Dockerfile, how to run databases with Docker, and how to wire everything together with Docker Compose.
Containers vs Virtual Machines
The most common misconception: containers are not virtual machines. A VM is a full house with its own plumbing and electrical system; a container is an apartment sharing the building's infrastructure but with its own locked door.
| Virtual Machine | Docker Container | |
|---|---|---|
| Virtualizes | Entire computer (CPU, memory, storage, OS) | Only the application environment |
| Kernel | Runs its own | Shares the host OS kernel |
| Memory | Heavy: 1β4 GB RAM per VM | Lightweight: 10β200 MB RAM |
| Startup | Slow: minutes | Fast: seconds |
| Isolation | Complete, from the host OS | Process-level, from the host OS |
Virtual Machines: Docker Containers:
ββββββββββββββββββββ ββββββββββββββββββββ
β App A App B β β Container Containerβ
β βββββββββββββββββ β ββββββββ ββββββββ β
β βGuest ββGuest ββ β β App β β App β β
β β OS ββ OS ββ β β Deps β β Deps β β
β βββββββββββββββββ β ββββββββ ββββββββ β
β Hypervisor β β Docker Engine β
β Host OS β β Host OS β
ββββββββββββββββββββ ββββββββββββββββββββFor web development, Docker containers are almost always the right choice.
Installing Docker
Download Docker Desktop from docker.com β available for Mac, Windows, and Linux. It includes Docker Engine, Docker CLI, and Docker Compose.
Verify the installation:
docker --version
# Docker version 27.0.3
docker compose version
# Docker Compose version v2.29.1Core Concepts: Image, Container, Registry
An image is a recipe; a container is the dish made from it β you can cook the same recipe many times and get many independent dishes.
- Image: A read-only blueprint containing the OS layer, your app's dependencies, and your app code. Built from a Dockerfile.
- Container: A running instance of an image. You can run many containers from one image simultaneously.
- Registry: A storage service for images. Docker Hub is the public registry; GitHub Container Registry (
ghcr.io) is popular for private images.
# Pull an image from Docker Hub
docker pull node:20-alpine
# Run a container from an image
docker run node:20-alpine node --version
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Stop a container
docker stop container_id
# Remove a container
docker rm container_id
# List images
docker images
# Remove an image
docker rmi image_nameYour First Dockerfile
A Dockerfile is a recipe for building a Docker image. Create one in your project root:
# syntax=docker/dockerfile:1
# Start from official Node.js 20 (Alpine = minimal Linux base)
FROM node:20-alpine
# Set working directory inside the container
WORKDIR /app
# Copy package files first (layer caching optimization)
COPY package.json package-lock.json ./
# Install dependencies
RUN npm ci --only=production
# Copy the rest of the application
COPY . .
# Expose the port your app listens on
EXPOSE 3000
# Command to run when container starts
CMD ["node", "server.js"]Layer Caching Explained
Docker builds images in layers. Each instruction is a layer. If a layer hasn't changed, Docker reuses the cached version β this is why COPY package*.json ./ and RUN npm ci come before COPY . .:
# Layer 1: Base image (rarely changes)
FROM node:20-alpine
# Layer 2: Working directory (rarely changes)
WORKDIR /app
# Layer 3: Dependencies (changes only when package.json changes)
COPY package.json package-lock.json ./
RUN npm ci
# Layer 4: App code (changes frequently)
COPY . .
# Without this order: every code change rebuilds dependencies
# With this order: code changes only rebuild layer 4Build and Run
# Build the image (-t tags it with a name)
docker build -t my-app:latest .
# Run a container from your image
docker run -p 3000:3000 my-app:latest
# β β
# host:port container:port
# Run in background (-d = detached)
docker run -d -p 3000:3000 --name my-app-container my-app:latest
# View logs
docker logs my-app-container
docker logs -f my-app-container # Follow (live)
# Open a shell inside the container (debugging)
docker exec -it my-app-container sh.dockerignore
Like .gitignore, but for Docker β exclude files from the build context:
node_modules
.git
.env
.env.local
npm-debug.log
dist
build
*.md
Dockerfile
.dockerignoreWithout this, COPY . . would copy node_modules (hundreds of MB) into the image, defeating the purpose of RUN npm ci.
Docker Compose: Multiple Services Together
Most web apps need multiple services. Here's a docker-compose.yml for a Node.js app with PostgreSQL and Redis:
# docker-compose.yml
version: '3.9'
services:
# Your web application
app:
build: .
ports:
- "3000:3000"
environment:
NODE_ENV: development
DATABASE_URL: postgresql://postgres:password@db:5432/myapp
REDIS_URL: redis://cache:6379
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
volumes:
- .:/app # Mount code for hot reload in dev
- /app/node_modules # Don't mount node_modules from host
# PostgreSQL database
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data # Persist data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
retries: 5
# Redis cache
cache:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data: # Named volume β persists between container restartsDocker Compose Commands
# Start all services (build if needed)
docker compose up
# Start in background
docker compose up -d
# Rebuild and start
docker compose up --build
# Stop all services
docker compose down
# Stop and remove volumes (clears database)
docker compose down -v
# View logs for all services
docker compose logs
# View logs for one service
docker compose logs app
# Run a command in a service
docker compose exec app sh
docker compose exec db psql -U postgres myappDevelopment vs Production Dockerfiles
For development, you want hot reload. For production, you want a minimal, fast image:
# Dockerfile.prod
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Multi-stage: final image only includes built output
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/server.js"]Multi-stage builds produce much smaller production images because build tools, TypeScript, and source files never make it into the final layer β only the compiled output does.
For understanding the SQL databases you'll run with Docker, our SQL for web developers guide covers everything you need. For the HTTP protocol that powers your containerized apps, see our HTTP vs HTTPS guide.
Further Reading
- Git for Beginners: Stop Fearing Version Control, Start Loving It
- Git and GitHub Complete Guide for Beginners β 2026 Edition
- CSS Grid vs Flexbox: When to Use Which Layout Method
- The Complete Guide to Web Performance in 2025: Make It Fast
- SQL for Web Developers: Database Basics You Can't Skip
- Python Testing with Pytest: Write Tests That Actually Catch Bugs
- JavaScript & React Complete Guide 2026 β From Basics to Pro
- Data Structures for Humans: Finally Understanding Arrays, Trees, Graphs
Advertisement
π¬ DiscussionPowered by GitHub Discussions
Frequently Asked Questions
Problem Solver and Cloud Expert
Solves complex infrastructure challenges and architects reliable, scalable cloud deployments for every project. Shamshur Rahman keeps AiTechWorldsβ hosting and cloud infrastructure fast, resilient, and cost-efficient.
Not sure yet? Ask AI about this article
Get an instant, unbiased AI summary of βDocker for Beginners: Containers Explained Without the Jargonβ.
Advertisement
Related Articles
Understanding APIs: A Beginner's Story About How Apps Talk
API tutorial for beginners β understand what APIs are, how REST APIs work, HTTP methods, JSON, authentication, and how to call APIs in JavaScript with real examples.
The Web Developer's Guide to Chrome DevTools (Hidden Features)
Chrome DevTools guide for web developers β master the Elements panel, Network tab, Console, Performance profiler, and hidden features most developers never use.
CSS Grid vs Flexbox: When to Use Which Layout Method
CSS Grid vs Flexbox explained clearly β understand the difference, when each layout method excels, and how to choose the right one for every UI pattern.
Git for Beginners: Stop Fearing Version Control, Start Loving It
Git tutorial for beginners β learn the essential git commands, branching, merging, and GitHub workflow with real examples that make version control click.