Skip to main content
โšก Calmops

Introduction to Docker and Containers

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.


Resources

Comments