[2026] Docker Compose Tutorial for Beginners | Multi-Container Apps Explained

[2026] Docker Compose Tutorial for Beginners | Multi-Container Apps Explained

이 글의 핵심

Docker Compose tutorial: services, networks, volumes, depends_on, and env files—run a Node app with MongoDB and Nginx from one docker-compose.yml with clear commands.

Introduction

Docker packages an app and its dependencies into an image; a running image is a container. When you need more than one container—for example a Node API, a database, and optionally Nginx—you can orchestrate them with Docker Compose: one docker-compose.yml and commands like docker compose up -d. This tutorial explains the mental model (services, networks, volumes) and gives a copy-paste example you can extend. For production-grade health checks and secrets, continue with Docker Compose for Node.js production.

Table of contents

  1. Core concepts
  2. Dockerfile recap
  3. Your first docker-compose.yml
  4. Daily commands
  5. Next steps

Core concepts

ConceptMeaning
ServiceOne container spec in Compose: image or build, ports, env, volumes.
ProjectDefault network name is derived from the project folder; all services in the file share it unless you customize networks.
Service DNSOther services resolve mongo, app, etc.—not localhost from one container to another.
VolumeNamed or bind mount to persist data (e.g. database files) when containers are recreated.
depends_onStart order hint; for ready semantics use health checks (see the production article).

Dockerfile recap

Compose often builds the API image from a Dockerfile: 아래 코드는 dockerfile를 사용한 구현 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.

# Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

Use a .dockerignore to exclude node_modules, .git, .env, and build artifacts.

Your first docker-compose.yml

Example: app + MongoDB + Nginx (reverse proxy). Adjust image tags and env for your project. 다음은 yaml를 활용한 상세한 구현 코드입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# docker-compose.yml
# 실행 예제
version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
      - MONGODB_URI=mongodb://mongo:27017/mydb
    depends_on:
      - mongo
    restart: unless-stopped
    volumes:
      - ./logs:/app/logs
  mongo:
    image: mongo:7
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
    restart: unless-stopped
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    restart: unless-stopped
volumes:
  mongo-data:

Why mongo:27017 in MONGODB_URI?
mongo is the service name—Docker’s embedded DNS resolves it inside the network.

Daily commands

아래 코드는 bash를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.

# Start in background
docker compose up -d
# Follow logs
docker compose logs -f
# Stop and remove containers (volumes kept unless -v)
docker compose down
# Restart services
docker compose restart
# Rebuild images after Dockerfile changes
docker compose up -d --build

Next steps


Conclusion

Compose turns multiple containers into a single declarative stack: same file for teammates, CI, and servers. Master service names, volumes, and up/down, then layer production concerns from the linked guides.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3