If you've ever heard the phrase "it works on my machine" and felt personally attacked, Docker is the tool that fixes that problem forever. In this guide, I'll walk you through installing Docker on both Mac and Windows, understanding the core concepts, running your first containers, writing a Dockerfile, and finally orchestrating multi-container apps with Docker Compose. By the end, you'll have a solid, practical foundation — not just theory.
What is Docker?
Docker is a platform that lets you package an application along with everything it needs (code, runtime, libraries, system tools) into a single unit called a container. Containers are lightweight, portable, and run the same way regardless of where they're deployed — your laptop, a teammate's machine, or a production server.
Think of it like a shipping container for software: no matter what's inside, it fits the same ship, truck, and crane.
Key terms you'll see a lot:
Image — A read-only template/blueprint for a container (like a snapshot of an app + its environment).
Container — A running instance of an image.
Dockerfile — A text file with instructions to build an image.
Docker Compose — A tool to define and run multi-container applications using a single YAML file.
Installing Docker on Mac
Go to the official Docker Desktop download page: docker.com/products/docker-desktop
Download Docker Desktop for Mac — choose the correct version based on your chip:
Apple Silicon (M1/M2/M3/M4)
Intel chip
Open the downloaded
.dmgfile and drag the Docker icon into your Applications folder.Launch Docker from Applications. It will ask for system permissions — allow them.
Wait for the whale icon 🐳 to appear in your menu bar. When it stops animating, Docker is running.
Verify the installation by opening Terminal and running:
bash
docker --version
docker run hello-worldIf you see a "Hello from Docker!" message, you're good to go.
Installing Docker on Windows
Make sure WSL 2 (Windows Subsystem for Linux) is enabled, since Docker Desktop on Windows relies on it. Open PowerShell as Administrator and run:
powershell
wsl --installRestart your computer if prompted.
Download Docker Desktop for Windows from docker.com/products/docker-desktop
Run the installer and make sure the checkbox for "Use WSL 2 instead of Hyper-V" is selected during setup.
After installation, restart your machine.
Launch Docker Desktop. It may take a minute to initialize the first time.
Verify the installation by opening Command Prompt or PowerShell:
powershell
docker --version
docker run hello-worldSame as Mac — if you see the "Hello from Docker!" message, Docker is correctly installed.
Basic Docker Commands
Once Docker is installed, here are the everyday commands you'll use constantly.
Check installed images:
bash
docker imagesPull an image from Docker Hub:
bash
docker pull nginxRun a container:
bash
docker run -d -p 8080:80 --name my-nginx nginx-d→ run in detached mode (background)-p 8080:80→ map port 8080 on your machine to port 80 in the container--name→ give the container a friendly name
Visit http://localhost:8080 in your browser — you should see the Nginx welcome page.
List running containers:
bash
docker psStop a container:
bash
docker stop my-nginxRemove a container:
bash
docker rm my-nginxRemove an image:
bash
docker rmi nginxView logs of a container:
bash
docker logs my-nginxEnter a running container's shell:
bash
docker exec -it my-nginx /bin/bashWriting Your First Dockerfile
A Dockerfile defines how your custom image is built. Let's containerize a simple Node.js app.
Project structure:
my-app/
├── Dockerfile
├── package.json
├── index.jsindex.js
javascript
const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello from inside a Docker container!');
});
server.listen(3000, () => console.log('Server running on port 3000'));Dockerfile
dockerfile
# Use an official Node.js runtime as the base image
FROM node:20-alpine
# Set the working directory inside the container
WORKDIR /app
# Copy package.json first (for caching layers efficiently)
COPY package.json ./
# Install dependencies
RUN npm install
# Copy the rest of the app's source code
COPY . .
# Expose the port the app runs on
EXPOSE 3000
# Command to run the app
CMD ["node", "index.js"]Build the image:
bash
docker build -t my-node-app .Run the container from your custom image:
bash
docker run -d -p 3000:3000 --name node-container my-node-appNow visit http://localhost:3000 to see your app running inside a container.
Introducing Docker Compose
Real-world applications usually involve multiple services — a backend, a database, maybe a cache like Redis. Running each with separate docker run commands gets messy fast. That's where Docker Compose comes in.
Docker Compose lets you define your entire application stack (all services, networks, and volumes) in one YAML file, then spin everything up with a single command.
Install check — Docker Compose comes bundled with Docker Desktop on both Mac and Windows, so no separate installation is needed. Verify with:
bash
docker compose versionExample: Node.js App + MongoDB with Docker Compose
Project structure:
my-app/
├── Dockerfile
├── docker-compose.yml
├── package.json
├── index.jsdocker-compose.yml
yaml
version: "3.9"
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- mongo
environment:
- MONGO_URL=mongodb://mongo:27017/mydb
mongo:
image: mongo:6
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
volumes:
mongo-data:What's happening here:
app— builds your Node.js app using the Dockerfile in the current directory, exposes port 3000, and waits formongoto start first.mongo— pulls the official MongoDB image and persists data using a named volume so your data survives container restarts.volumes— a persistent storage location managed by Docker, independent of the container's lifecycle.
Start everything:
bash
docker compose up -dCheck running services:
bash
docker compose psView logs from all services:
bash
docker compose logs -fStop everything:
bash
docker compose downStop and remove volumes too (careful — this deletes your data):
bash
docker compose down -vQuick Reference Cheat Sheet
Task | Command |
|---|---|
Check Docker version |
|
Pull an image |
|
Run a container |
|
List running containers |
|
Stop a container |
|
Build an image |
|
Start Compose stack |
|
Stop Compose stack |
|
Wrapping Up
You now know how to:
Install Docker on both Mac and Windows
Understand images vs. containers
Run and manage containers using core CLI commands
Write a Dockerfile to containerize your own app
Use Docker Compose to run multi-service applications
Docker takes a bit of practice to feel natural, but once it clicks, you'll wonder how you ever managed dependencies and environments without it. The best next step is to containerize one of your own projects - pick something small, write the Dockerfile, and get it running.
Happy containerizing!