Back to Blog
    DevOps

    Docker for Beginners: Containers, Images & Docker Compose Explained Simply (2026)

    Mortex SolutionsMarch 1, 202614 min read
    Docker for Beginners: Containers, Images & Docker Compose Explained Simply (2026)

    If you've heard developers say "but it works on my machine!" — Docker solves exactly that problem. Docker packages your application with everything it needs (code, runtime, libraries) into a container that runs identically everywhere. This beginner guide makes Docker easy to understand and use.

    Docker containers concept

    📦 What is Docker?

    Docker is a platform that lets you package, ship, and run applications in isolated environments called containers. Unlike virtual machines, containers share the host OS kernel, making them incredibly lightweight and fast.

    🆚 Containers vs Virtual Machines

    FeatureContainersVirtual Machines
    Startup TimeSecondsMinutes
    SizeMBsGBs
    PerformanceNear-nativeOverhead from hypervisor
    IsolationProcess-levelFull OS-level
    OSShares host kernelOwn OS per VM

    🔧 Installing Docker

    # macOS
    brew install --cask docker
    
    # Ubuntu
    sudo apt-get update
    sudo apt-get install docker.io docker-compose-v2
    sudo systemctl start docker
    
    # Windows — Download Docker Desktop from docker.com
    
    # Verify installation
    docker --version
    docker run hello-world

    🐳 Your First Container

    # Run an Nginx web server in a container
    docker run -d -p 8080:80 --name my-web nginx
    
    # Now visit http://localhost:8080 — you have a web server running!
    
    # See running containers
    docker ps
    
    # View logs
    docker logs my-web
    
    # Stop and remove
    docker stop my-web
    docker rm my-web

    📝 Writing a Dockerfile

    A Dockerfile is a recipe for building your own container image:

    # Dockerfile for a Node.js application
    FROM node:22-alpine
    
    # Set working directory
    WORKDIR /app
    
    # Copy package files first (better caching)
    COPY package*.json ./
    
    # Install dependencies
    RUN npm ci --only=production
    
    # Copy application code
    COPY . .
    
    # Expose port
    EXPOSE 3000
    
    # Start the app
    CMD ["node", "server.js"]
    # Build the image
    docker build -t my-node-app .
    
    # Run it
    docker run -d -p 3000:3000 my-node-app
    
    # Visit http://localhost:3000

    🎼 Docker Compose — Multi-Container Apps

    Most real apps need multiple services (app + database + cache). Docker Compose manages them all:

    # docker-compose.yml
    services:
      app:
        build: .
        ports:
          - "3000:3000"
        environment:
          - DATABASE_URL=postgres://user:pass@db:5432/myapp
          - REDIS_URL=redis://cache:6379
        depends_on:
          - db
          - cache
    
      db:
        image: postgres:16-alpine
        environment:
          POSTGRES_USER: user
          POSTGRES_PASSWORD: pass
          POSTGRES_DB: myapp
        volumes:
          - pgdata:/var/lib/postgresql/data
    
      cache:
        image: redis:7-alpine
    
    volumes:
      pgdata:
    # Start everything with one command
    docker compose up -d
    
    # View all running services
    docker compose ps
    
    # View logs from all services
    docker compose logs -f
    
    # Stop everything
    docker compose down

    📋 Essential Docker Commands

    CommandDescription
    docker imagesList all local images
    docker exec -it container bashOpen shell inside container
    docker system pruneClean up unused resources
    docker volume lsList persistent volumes
    docker network lsList Docker networks
    🐳 Docker Best Practices: Always use specific image tags (e.g., node:22-alpine not node:latest), use multi-stage builds to reduce image size, add a .dockerignore file, and never store secrets in your Dockerfile. Use environment variables or Docker secrets instead.