Compose Basics and Services

Back

Loading concept...

🎭 Docker Compose: Your Orchestra Conductor

Imagine you’re a conductor of a music orchestra. Each musician (violinist, drummer, pianist) is talented, but alone they just make noise. You bring them together, tell them when to start, how loud to play, and make them work as one beautiful symphony.

Docker Compose is exactly that conductor for your containers!


🎯 What is Docker Compose?

Think of it like this:

Without Compose: You run to each musician, tap their shoulder, whisper instructions, run to the next one… exhausting!

With Compose: You write ONE sheet of music. All musicians read it. Everyone knows what to do. Magic!

Docker Compose lets you:

  • Define multiple containers in ONE file
  • Start them all with ONE command
  • Make them talk to each other automatically

Real Example: You have a website that needs:

  • A web server (plays the melody)
  • A database (keeps the rhythm)
  • A cache (adds the sparkle)

Without Compose: 3 long commands, remember the order, hope nothing breaks.

With Compose: docker compose up — Done! ✨


📜 The Magic Sheet: docker-compose.yml

The docker-compose.yml file is your recipe book. It tells Docker exactly what to cook and how.

Basic Structure

version: "3.8"

services:
  web:
    image: nginx
    ports:
      - "80:80"

  database:
    image: postgres
    environment:
      POSTGRES_PASSWORD: secret

Let’s break this down like LEGO blocks:

Block What It Does
version Which recipe language to use
services List of all your containers
web Name of your first container
image What picture to use for this container

🧱 The Building Blocks

docker-compose.yml
├── version      → Recipe version
├── services     → Your containers
├── networks     → How they talk
└── volumes      → Where they store stuff

🎪 Services: Your Container Team

Each service is like a team member with a specific job.

Simple Service Example

services:
  my-app:
    image: node:18
    container_name: awesome-app
    restart: always

What each line means:

Line Plain English
my-app: “Hey, I’m calling this team member ‘my-app’”
image: “Use this ready-made container image”
container_name: “Give it this nickname”
restart: “If it crashes, wake it up again”

🔄 Restart Options (Like an Alarm Clock)

restart: "no"        # Never wake up
restart: always      # Always wake up
restart: on-failure  # Wake up only if something went wrong
restart: unless-stopped  # Keep running unless I say stop

Multiple Services Working Together

services:
  frontend:
    image: react-app
    depends_on:
      - backend

  backend:
    image: node-api
    depends_on:
      - database

  database:
    image: postgres
graph TD A["Frontend"] -->|waits for| B["Backend"] B -->|waits for| C["Database"] C -->|starts first| C

The depends_on is like saying: “Don’t start the show until the band is ready!”


🏗️ Build Configuration: Making Your Own Containers

Sometimes you don’t want a pre-made image. You want to cook from scratch!

Basic Build

services:
  my-custom-app:
    build: .

This says: “Look in the current folder for a Dockerfile and build it!”

Advanced Build Options

services:
  my-custom-app:
    build:
      context: ./app
      dockerfile: Dockerfile.dev
      args:
        NODE_ENV: development
Option What It Does
context “Look in THIS folder for files”
dockerfile “Use THIS specific recipe file”
args “Here are some ingredients to pass in”

🎭 Build vs Image

# Option 1: Use a ready-made image
services:
  app:
    image: nginx:latest

# Option 2: Build your own
services:
  app:
    build: ./my-app

# Option 3: Build AND name it
services:
  app:
    build: ./my-app
    image: my-custom-image:v1

Think of it like:

  • image: → Buy a cake from the store
  • build: → Bake the cake yourself
  • Both → Bake it AND give it a fancy name

🚪 Ports: Opening the Doors

Ports are like doors to your container. Without opening them, nobody can come in!

Port Mapping Syntax

services:
  web:
    image: nginx
    ports:
      - "8080:80"

The format: "HOST:CONTAINER"

Your Computer:8080  →  Container:80
     ↑                      ↑
  You knock here    It answers here

Different Ways to Open Doors

ports:
  # Short syntax
  - "3000:3000"      # Same door number
  - "8080:80"        # Different numbers
  - "127.0.0.1:3000:3000"  # Only local access

  # Long syntax (clearer)
  - target: 80       # Container's door
    published: 8080  # Your door
    protocol: tcp    # Type of visitor

🎯 Quick Reference

What You Write What Happens
"80:80" Visit localhost:80 → reaches container’s port 80
"3000:80" Visit localhost:3000 → reaches container’s port 80
"80" Random port on host → container’s port 80

💾 Volumes: The Memory Boxes

Containers are forgetful. When they stop, they forget everything! Volumes are like memory boxes that save things.

Why Volumes Matter

graph TD A["Container Stops"] -->|Without Volume| B["Data Lost Forever 😢"] A -->|With Volume| C["Data Safe & Sound 😊"]

Volume Types

services:
  database:
    image: postgres
    volumes:
      # Named volume (Docker manages it)
      - db-data:/var/lib/postgresql/data

      # Bind mount (your folder)
      - ./my-files:/app/files

      # Read-only mount
      - ./config:/app/config:ro

volumes:
  db-data:  # Declare named volumes here

📦 Volume Cheat Sheet

Type Syntax Use When
Named mydata:/path Database files, persistent data
Bind ./local:/container Development, live code changes
Read-only ./config:/path:ro Config files that shouldn’t change

Example: Development Setup

services:
  app:
    build: .
    volumes:
      - ./src:/app/src        # Live code reload
      - node_modules:/app/node_modules  # Cache

volumes:
  node_modules:

🌐 Networks: The Communication Highways

Networks let your containers talk to each other like neighbors over a fence.

The Magic of Default Networks

When you run docker compose up, Compose creates a secret network automatically!

services:
  web:
    image: nginx

  api:
    image: node-api

These can talk using their service names:

  • web can reach api by calling http://api
  • api can reach web by calling http://web

No IP addresses needed! 🎉

Custom Networks

services:
  frontend:
    networks:
      - front-tier

  backend:
    networks:
      - front-tier
      - back-tier

  database:
    networks:
      - back-tier

networks:
  front-tier:
  back-tier:
graph LR subgraph front-tier A["Frontend"] B["Backend"] end subgraph back-tier B C["Database"] end

🔒 Why Custom Networks?

Without Custom Networks With Custom Networks
Everyone can talk to everyone Controlled communication
Less secure More secure
Simple setups Production apps

Network Configuration Options

networks:
  my-network:
    driver: bridge          # Default, most common
    driver_opts:
      com.docker.network.bridge.name: my-bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

🎬 Putting It All Together

Here’s a complete example — a web app with a database:

version: "3.8"

services:
  web:
    build: ./frontend
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    depends_on:
      - api
    networks:
      - app-network

  api:
    build: ./backend
    ports:
      - "5000:5000"
    environment:
      - DB_HOST=database
      - DB_PORT=5432
    depends_on:
      - database
    networks:
      - app-network

  database:
    image: postgres:15
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=secret
    networks:
      - app-network

volumes:
  db-data:

networks:
  app-network:

🚀 Running Your Symphony

# Start everything
docker compose up

# Start in background
docker compose up -d

# Stop everything
docker compose down

# Stop and remove volumes
docker compose down -v

🎯 Key Commands Quick Reference

Command What It Does
docker compose up Start all services
docker compose up -d Start in background
docker compose down Stop and remove
docker compose ps List running services
docker compose logs See all logs
docker compose build Build/rebuild images

🌟 Remember This!

  1. docker-compose.yml = Your master recipe
  2. Services = Individual containers with jobs
  3. Build = Make your own container from Dockerfile
  4. Ports = Doors to let traffic in
  5. Volumes = Memory boxes for data
  6. Networks = Highways for containers to talk

You’re now ready to conduct your own container orchestra! 🎭🎵

Pro Tip: Start simple. Add one feature at a time. Test often. That’s the secret to becoming a Compose master!

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.