Introduction
Docker changed how we build, ship, and run applications. Containers provide consistent environments across development and production. This guide introduces Docker fundamentals.
What Is Docker
Containers vs VMs
| Containers | Virtual Machines |
|---|---|
| Share OS kernel | Full OS per VM |
| Lightweight | Heavy |
| Fast start | Slow start |
| MB size | GB size |
Benefits
- Consistent environments
- Isolation
- Resource efficiency
- Easy deployment
Key Concepts
Image
- Template for containers
- Read-only
- Layered filesystem
Container
- Running instance of image
- Writable layer
- Isolated process
Registry
- Storage for images
- Docker Hub (public)
- Private registries
Getting Started
Installation
# macOS
brew install --cask docker
# Linux
curl -fsSL https://get.docker.com | sh
# Verify
docker --version
Hello World
docker run hello-world
Running a Container
docker run -d -p 8080:80 nginx
-d: Detached (background)-p 8080:80: Port mapping
Working with Images
Pull Image
docker pull nginx:latest
List Images
docker images
Remove Image
docker rmi nginx:latest
Working with Containers
List Running Containers
docker ps
List All Containers
docker ps -a
Stop Container
docker stop container_id
Remove Container
docker rm container_id
View Logs
docker logs container_id
Building Images
Dockerfile
# Base image
FROM node:20-alpine
# Working directory
WORKDIR /app
# Copy files
COPY package*.json ./
COPY . .
# Install dependencies
RUN npm install
# Expose port
EXPOSE 3000
# Start command
CMD ["npm", "start"]
Build Image
docker build -t myapp:latest .
Tag Image
docker tag myapp:latest registry/myapp:v1.0
Docker Compose
docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:15
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=secret
volumes:
postgres_data:
Commands
# Start all services
docker-compose up -d
# Stop all services
docker-compose down
# View logs
docker-compose logs -f
Common Patterns
Multi-stage Builds
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
Development with Volumes
services:
app:
build: .
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
Best Practices
Dockerfile
# Use specific versions
FROM node:20-alpine
# Layer caching
COPY package*.json ./
RUN npm install
COPY . .
# Non-root user
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -D appuser
USER appuser
# Multi-line commands
RUN apk add --no-cache \
curl \
&& rm -rf /var/cache/apk/*
Image Size
- Use Alpine base
- Multi-stage builds
- .dockerignore
- Clean up in same layer
.dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
Networking
Bridge Network
docker network create mynetwork
docker run -d --network mynetwork --name app1 myapp
docker run -d --network mynetwork --name app2 myapp
Docker Networks
- bridge: Default
- host: Host network
- none: No networking
Data Management
Volumes
# Named volume
docker volume create mydata
docker run -v mydata:/app/data myapp
Bind Mounts
# Development
docker run -v $(pwd):/app myapp
Docker Hub
Push Image
docker login
docker push username/myapp:latest
Pull Image
docker pull username/myapp:latest
Conclusion
Docker simplifies deployment and ensures consistency. Start with basic containers, then add Docker Compose for multi-container apps. The ecosystem has great tools for development and production.
Comments