Docker Basics
Docker is a platform for developing, shipping, and running applications in containers. Containers are lightweight, portable, and isolated environments.
Key Concepts
| Concept | Description |
|---|---|
Image | Blueprint/template for containers (read-only) |
Container | Running instance of an image |
Dockerfile | Instructions to build an image |
Registry | Storage for images (Docker Hub) |
Volume | Persistent storage for containers |
Bash
# Check Docker installation
docker --version
docker info
# Run your first container
docker run hello-world
# Run interactive container
docker run -it ubuntu bash
# Run in background (detached)
docker run -d nginx
Docker Images
Bash
# List images
docker images
docker image ls
# Pull image from registry
docker pull nginx
docker pull node:18-alpine
# Remove image
docker rmi nginx
docker image rm nginx
# Remove unused images
docker image prune
# Search images on Docker Hub
docker search python
# Build image from Dockerfile
docker build -t myapp:1.0 .
docker build -t myapp:latest -f Dockerfile.prod .
# Tag image
docker tag myapp:1.0 username/myapp:1.0
# Push to registry
docker login
docker push username/myapp:1.0
# Image history
docker history nginx
# Inspect image
docker inspect nginx
Container Management
Bash
# List containers
docker ps # Running containers
docker ps -a # All containers
# Run container
docker run nginx
docker run -d nginx # Detached
docker run -d --name my-nginx nginx # Named container
docker run -d -p 8080:80 nginx # Port mapping
docker run -d -p 8080:80 -v /host:/container nginx # Volume
docker run -d --rm nginx # Auto-remove on stop
docker run -e ENV_VAR=value nginx # Environment variable
docker run --env-file .env nginx # Env file
# Start/Stop/Restart
docker start container_id
docker stop container_id
docker restart container_id
# Remove containers
docker rm container_id
docker rm -f container_id # Force remove running
docker container prune # Remove stopped containers
# Execute command in running container
docker exec -it container_id bash
docker exec container_id ls /app
# View logs
docker logs container_id
docker logs -f container_id # Follow logs
docker logs --tail 100 container_id
# Container stats
docker stats
# Copy files
docker cp myfile.txt container_id:/app/
docker cp container_id:/app/file.txt ./
Dockerfile
Dockerfile
# Node.js Application Dockerfile
FROM node:18-alpine
# Set working directory
WORKDIR /app
# Copy package files first (for caching)
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
# Run as non-root user
USER node
# Start command
CMD ["node", "server.js"]
Multi-Stage Build
Dockerfile
# Build stage
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/server.js"]
Dockerfile Instructions
| Instruction | Description |
|---|---|
FROM | Base image |
WORKDIR | Set working directory |
COPY | Copy files from host |
ADD | Copy + extract archives + URLs |
RUN | Execute commands during build |
CMD | Default command (overridable) |
ENTRYPOINT | Container entry point |
ENV | Set environment variable |
ARG | Build-time variable |
EXPOSE | Document port |
VOLUME | Create mount point |
Docker Compose
Docker Compose is a tool for defining and running multi-container applications.
docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://db:5432/myapp
depends_on:
- db
- redis
volumes:
- ./app:/app
networks:
- app-network
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- app-network
redis:
image: redis:alpine
networks:
- app-network
volumes:
postgres-data:
networks:
app-network:
driver: bridge
Bash
# Docker Compose commands
docker-compose up # Start services
docker-compose up -d # Detached
docker-compose up --build # Rebuild images
docker-compose down # Stop and remove
docker-compose down -v # Also remove volumes
docker-compose ps # List services
docker-compose logs # View logs
docker-compose logs -f web # Follow specific service
docker-compose exec web bash # Execute command
docker-compose restart web # Restart service
docker-compose pull # Pull latest images
docker-compose build # Build images
Docker Networking
Bash
# List networks
docker network ls
# Create network
docker network create my-network
docker network create --driver bridge my-bridge
# Connect container to network
docker network connect my-network container_id
docker network disconnect my-network container_id
# Run container on specific network
docker run -d --network my-network --name web nginx
# Inspect network
docker network inspect my-network
# Remove network
docker network rm my-network
docker network prune
| Network Driver | Use Case |
|---|---|
bridge | Default. Isolated network on single host |
host | Use host's network directly |
none | No networking |
overlay | Multi-host networking (Swarm) |
Docker Volumes
Bash
# List volumes
docker volume ls
# Create volume
docker volume create my-volume
# Use volume
docker run -d -v my-volume:/data nginx
docker run -d --mount source=my-volume,target=/data nginx
# Bind mount (host directory)
docker run -d -v /host/path:/container/path nginx
docker run -d -v $(pwd):/app node
# Read-only mount
docker run -d -v my-volume:/data:ro nginx
# Inspect volume
docker volume inspect my-volume
# Remove volume
docker volume rm my-volume
docker volume prune
Best Practices:
• Use multi-stage builds to reduce image size
• Don't run containers as root
• Use .dockerignore to exclude unnecessary files
• Pin specific image versions in production
• Use health checks for production containers
• Use multi-stage builds to reduce image size
• Don't run containers as root
• Use .dockerignore to exclude unnecessary files
• Pin specific image versions in production
• Use health checks for production containers