튜토리얼

Docker Compose 활용 다중 서비스 로컬 개발 환경 구축 실전 가이드

강코의 코딩 일기 2026. 6. 27. 13:14
반응형

복잡한 다중 서비스 개발 환경 설정에 지쳤다면? Docker Compose로 백엔드, 프론트엔드, 데이터베이스를 한 번에 관리하는 실전 가이드를 통해 효율적인 로컬 개발 환경을 구축하고 생산성을 극대화하세요.

개발자라면 누구나 한 번쯤 겪어봤을 문제입니다. 백엔드, 프론트엔드, 데이터베이스, 캐시 서버 등 여러 서비스로 구성된 프로젝트를 로컬에서 개발해야 할 때, 각 서비스의 의존성을 맞추고, 환경을 설정하며, 서로 다른 포트 충돌을 해결하는 과정은 결코 쉽지 않습니다. 특히 여러 개발자가 함께 작업하는 팀 환경에서는 "내 컴퓨터에서는 되는데?"라는 말이 흔하게 나오기 마련입니다. 이러한 비효율적인 환경 설정은 개발 초기 단계부터 생산성을 저해하고 불필요한 스트레스를 유발합니다.

이런 복잡한 문제를 해결하고 싶으신가요? Docker Compose는 바로 이 지점에서 빛을 발합니다. 단일 명령어로 다중 컨테이너 애플리케이션을 정의하고 실행할 수 있게 해주는 도구로, 개발 환경을 일관되고 재현 가능하게 만들어줍니다. 이 가이드에서는 Docker Compose를 활용하여 백엔드, 프론트엔드, 데이터베이스를 아우르는 다중 서비스 로컬 개발 환경을 구축하는 실전 노하우를 상세하게 다룹니다. 이제 더 이상 환경 설정에 시간을 낭비하지 않고, 핵심 개발에 집중할 수 있게 될 것입니다.

📑 목차

Docker Compose를 활용한 다중 서비스 로컬 개발 환경 구축 실전 가이드 - belgium, antwerp, shipping, container, freight, cargo, transport, harbor, container, container, container, freight, cargo, cargo, cargo, cargo, cargo

Image by 2427999 on Pixabay

다중 서비스 개발 환경, 왜 Docker Compose가 필수인가?

전통적인 방식의 다중 서비스 개발 환경 구축은 여러 가지 어려움을 동반합니다. 각 서비스마다 다른 런타임 버전(예: Node.js 14와 16), 데이터베이스 종류(MySQL과 PostgreSQL), 그리고 필요한 외부 라이브러리(Redis, Kafka 등)가 다를 수 있습니다. 이들을 모두 로컬 머신에 설치하고 관리하는 것은 버전 충돌, 의존성 문제, 그리고 지저분한 개발 환경으로 이어지기 쉽습니다.

Docker Compose는 이러한 문제들을 해결하는 강력한 솔루션입니다. 각 서비스를 독립적인 컨테이너로 격리하고, 이 컨테이너들을 YAML 파일 하나로 정의하여 관리합니다. 덕분에 얻을 수 있는 핵심적인 이점은 다음과 같습니다.

  • 환경 일관성: 모든 팀원이 동일한 개발 환경을 가질 수 있어 "내 컴퓨터에서는 되는데?" 문제를 없앱니다.
  • 빠른 온보딩: 새로운 팀원이 합류했을 때, 단 몇 줄의 명령어로 모든 개발 환경을 구축할 수 있습니다.
  • 격리된 의존성: 각 서비스의 의존성이 독립적인 컨테이너 내부에 존재하므로, 호스트 시스템을 오염시키지 않습니다.
  • 간편한 관리: 모든 서비스를 하나의 설정 파일로 관리하고, 단일 명령어로 시작/중지/재시작할 수 있습니다.

기존의 수동 설정 방식과 Docker Compose를 비교해보면 그 효율성을 더욱 명확히 알 수 있습니다.

특징 수동 설정 방식 Docker Compose 활용
환경 일관성 개발자마다 상이, 버전 충돌 가능성 높음 모든 개발자에게 동일한 환경 제공
설정 복잡성 각 서비스별 개별 설치 및 설정 필요, 시간 소모 YAML 파일 하나로 전체 환경 정의, 단일 명령어 실행
의존성 관리 호스트 시스템에 직접 설치, 버전 충돌 취약 각 컨테이너 내부에 격리, 호스트 시스템 영향 없음
새로운 개발자 온보딩 설치 가이드 숙지 및 수동 설정, 수 일 소요 몇 분 내에 개발 환경 구축 완료
자원 활용 호스트 시스템에 직접 설치, 삭제 어려움 필요할 때만 컨테이너 실행, 사용 후 쉽게 제거

이러한 장점들을 고려할 때, 다중 서비스 개발 환경에서 Docker Compose는 선택이 아닌 필수에 가깝습니다. 이제 Docker Compose의 기본적인 개념과 설치 방법을 알아보겠습니다.

Docker Compose, 시작하기 위한 기본 개념과 설치

Docker Compose란 무엇인가?

Docker Compose는 여러 개의 Docker 컨테이너를 함께 정의하고 실행하기 위한 도구입니다. 복잡한 다중 컨테이너 애플리케이션을 YAML 파일 하나로 구성하여, 단일 명령어로 모든 서비스를 시작하거나 중지할 수 있도록 돕습니다. 예를 들어, 웹 애플리케이션을 개발할 때 백엔드 API 서버, 데이터베이스, 프론트엔드 웹 서버 등을 각각 컨테이너로 실행해야 하는데, Docker Compose는 이 모든 컨테이너를 하나의 "서비스 묶음"으로 관리하게 해줍니다.

핵심 구성 요소는 다음과 같습니다.

  • 서비스(Services): 애플리케이션의 각 컴포넌트입니다. 예를 들어, '웹 서버', '데이터베이스', '캐시 서버' 등이 서비스가 될 수 있습니다. 각 서비스는 특정 Docker 이미지로부터 생성됩니다.
  • 네트워크(Networks): 컨테이너 간의 통신을 위한 가상 네트워크를 정의합니다. 기본적으로 Docker Compose는 모든 서비스에 대해 단일 네트워크를 생성하여 서비스 간 통신을 가능하게 합니다.
  • 볼륨(Volumes): 컨테이너가 삭제되더라도 데이터가 유지될 수 있도록 컨테이너 외부에 데이터를 저장하는 방식입니다. 개발 환경에서는 소스 코드를 호스트와 컨테이너 간에 공유하여 실시간으로 변경 사항을 반영하는 데 주로 사용됩니다.

Docker Compose 설치 및 기본 확인

Docker Compose를 사용하기 위해서는 먼저 Docker Engine이 설치되어 있어야 합니다. Docker Desktop을 설치하면 Docker Engine과 함께 Docker Compose가 자동으로 설치됩니다. macOS, Windows, Linux 등 운영체제에 맞는 Docker Desktop을 설치해주세요.

설치 후 터미널(또는 명령 프롬프트)에서 다음 명령어를 실행하여 Docker와 Docker Compose가 제대로 설치되었는지 확인할 수 있습니다.

docker --version
docker compose version

만약 `docker compose` 명령어가 인식되지 않는다면, 구형 Docker Compose 버전일 수 있습니다. 구형 버전은 `docker-compose` (하이픈 포함) 명령어를 사용하며, 별도로 설치해야 할 수도 있습니다. 하지만 최신 Docker Desktop에는 `docker compose` (하이픈 없음) 명령어가 기본적으로 포함되어 있습니다.

이제 Docker Compose의 기본 개념과 설치가 완료되었으니, 실제로 다중 서비스 환경을 어떻게 설계할지 알아보겠습니다.

다중 서비스 로컬 개발 환경 설계하기: 어떤 서비스를 연결할까?

다중 서비스 로컬 개발 환경을 구축하기 전에, 어떤 서비스들이 필요한지 명확히 정의하고 각 서비스 간의 관계를 파악하는 것이 중요합니다. 일반적인 웹 애플리케이션 개발 환경을 예로 들어보겠습니다.

  • 프론트엔드 서비스: React, Vue.js, Angular 등 JavaScript 프레임워크 기반의 웹 애플리케이션.
  • 백엔드 서비스: Node.js (Express), Python (Django/Flask), Java (Spring Boot), Go 등 API 서버.
  • 데이터베이스: PostgreSQL, MySQL, MongoDB 등 데이터를 저장하고 관리하는 시스템.
  • 캐시 서비스: Redis, Memcached 등 데이터베이스 부하를 줄이고 응답 속도를 향상시키는 캐싱 시스템.

이러 외에도 메시지 큐(RabbitMQ, Kafka), 검색 엔진(Elasticsearch) 등 다양한 서비스가 추가될 수 있습니다. 여기서는 프론트엔드 (React), 백엔드 (Node.js), 데이터베이스 (PostgreSQL)의 세 가지 서비스를 중심으로 환경을 설계해보겠습니다.

프로젝트 디렉토리 구조 설계

Docker Compose를 사용할 때는 각 서비스의 소스 코드와 Docker 관련 파일을 체계적으로 관리하는 것이 좋습니다. 일반적인 권장 디렉토리 구조는 다음과 같습니다.

.
├── docker-compose.yml           # Docker Compose 설정 파일
├── backend/                     # 백엔드 서비스 디렉토리
│   ├── Dockerfile               # 백엔드 Dockerfile
│   ├── package.json
│   ├── server.js
│   └── ...
├── frontend/                    # 프론트엔드 서비스 디렉토리
│   ├── Dockerfile               # 프론트엔드 Dockerfile
│   ├── package.json
│   ├── src/
│   └── public/
└── README.md

최상위 디렉토리에 docker-compose.yml 파일을 두고, 각 서비스별로 별도의 서브 디렉토리를 생성하여 해당 서비스의 소스 코드와 Dockerfile을 관리합니다. 이렇게 하면 각 서비스의 컨테이너 이미지를 빌드할 때 필요한 컨텍스트를 명확히 지정할 수 있습니다.

서비스 간 통신 및 포트 매핑 고려사항

  • 내부 통신: Docker Compose는 기본적으로 모든 서비스에 대해 단일 네트워크를 생성합니다. 이 네트워크 내에서 컨테이너들은 서비스 이름을 호스트명처럼 사용하여 서로 통신할 수 있습니다. 예를 들어, 백엔드 서비스는 데이터베이스 컨테이너를 db라는 이름으로 접근할 수 있습니다.
  • 외부 노출: 로컬 개발 환경에서 브라우저를 통해 프론트엔드에 접속하거나, Postman 등으로 백엔드 API를 테스트하려면 호스트 머신의 특정 포트를 컨테이너의 포트에 매핑해야 합니다. 예를 들어, 프론트엔드 컨테이너의 3000번 포트를 호스트의 3000번 포트로, 백엔드 컨테이너의 5000번 포트를 호스트의 5000번 포트로 매핑할 수 있습니다.
  • 데이터베이스 포트: 데이터베이스는 일반적으로 외부에서 직접 접근할 필요가 없으므로, 백엔드 서비스에서만 내부적으로 접근하도록 설정할 수 있습니다. 하지만 DBeaver 같은 GUI 툴로 로컬 데이터베이스에 접속해야 한다면, 호스트 포트를 매핑하는 것이 편리합니다.

이러한 설계를 바탕으로 이제 docker-compose.yml 파일을 작성하는 실전 가이드로 넘어가겠습니다.

Docker Compose를 활용한 다중 서비스 로컬 개발 환경 구축 실전 가이드 - computer, laptop, tech, blue computer, blue laptop, blue tech, computer, laptop, tech, tech, tech, tech, tech

Image by yeiferr on Pixabay

Docker Compose 파일 작성 실전: 단계별 가이드

이제 앞서 설계한 프론트엔드(React), 백엔드(Node.js), 데이터베이스(PostgreSQL) 세 가지 서비스를 docker-compose.yml 파일로 정의해보겠습니다. 이 과정에서 각 서비스의 Dockerfile도 함께 작성합니다.

백엔드 서비스 (Node.js) Dockerfile

backend/Dockerfile

# Node.js 런타임 이미지 사용
FROM node:18-alpine

# 컨테이너 내 작업 디렉토리 설정
WORKDIR /app

# package.json과 package-lock.json 복사
# 캐싱을 위해 종속성 파일 먼저 복사
COPY package*.json ./

# 종속성 설치
RUN npm install

# 모든 소스 코드 복사
COPY . .

# 애플리케이션 포트 노출
EXPOSE 5000

# 애플리케이션 실행 명령어
CMD ["npm", "start"]

Dockerfile은 Node.js 18 런타임을 기반으로 /app 디렉토리에 소스 코드를 복사하고, 종속성을 설치한 후 5000번 포트로 애플리케이션을 실행합니다.

프론트엔드 서비스 (React) Dockerfile

frontend/Dockerfile

# Node.js 런타임 이미지 사용 (빌드 단계)
FROM node:18-alpine as build

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

# React 애플리케이션 빌드 (정적 파일 생성)
RUN npm run build

# Nginx를 사용하여 빌드된 정적 파일 서빙 (런타임 단계)
FROM nginx:alpine

# Nginx 기본 설정 파일 제거
RUN rm /etc/nginx/conf.d/default.conf

# 사용자 정의 Nginx 설정 파일 복사
COPY nginx.conf /etc/nginx/conf.d/default.conf

# 빌드 단계에서 생성된 정적 파일 복사
COPY --from=build /app/build /usr/share/nginx/html

# 80번 포트 노출 (Nginx 기본 포트)
EXPOSE 80

# Nginx 실행
CMD ["nginx", "-g", "daemon off;"]

프론트엔드는 멀티스테이지 빌드를 사용하여 최종 이미지 크기를 최적화합니다. 첫 번째 스테이지에서 React 앱을 빌드하고, 두 번째 스테이지에서는 Nginx를 사용하여 빌드된 정적 파일을 서빙합니다. nginx.conf 파일은 프론트엔드 프로젝트의 frontend/nginx.conf 경로에 위치하며 다음과 같이 작성될 수 있습니다.

server {
    listen 80;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
        try_files $uri $uri/ /index.html;
    }

    # 백엔드 API 요청 프록시 (선택 사항)
    # location /api {
    #    proxy_pass http://backend:5000;
    #    proxy_http_version 1.1;
    #    proxy_set_header Upgrade $http_upgrade;
    #    proxy_set_header Connection 'upgrade';
    #    proxy_set_header Host $host;
    #    proxy_cache_bypass $http_upgrade;
    # }
}

주석 처리된 /api 프록시 설정은 프론트엔드에서 백엔드로 요청을 보낼 때 CORS 문제를 해결하고 싶을 때 유용합니다. 여기서는 backend라는 서비스 이름으로 백엔드 컨테이너에 접근합니다.

Docker Compose 파일 (docker-compose.yml) 작성

이제 모든 서비스의 Dockerfile이 준비되었으니, docker-compose.yml 파일을 작성하여 이들을 하나의 애플리케이션으로 묶습니다.

version: '3.8' # Docker Compose 파일 형식 버전 지정

services:
  # 1. 백엔드 서비스 정의
  backend:
    build:
      context: ./backend # backend 디렉토리에서 Dockerfile을 찾아 빌드
      dockerfile: Dockerfile
    ports:
      - "5000:5000" # 호스트의 5000번 포트를 컨테이너의 5000번 포트에 매핑
    volumes:
      - ./backend:/app # 호스트의 backend 디렉토리를 컨테이너의 /app에 마운트 (코드 변경 실시간 반영)
      - /app/node_modules # node_modules는 호스트와 동기화하지 않음 (컨테이너 내부에 유지)
    environment: # 환경 변수 설정
      DATABASE_URL: postgres://user:password@db:5432/mydatabase
      NODE_ENV: development
    depends_on: # db 서비스가 먼저 시작되도록 의존성 설정
      - db
    networks: # 서비스가 사용할 네트워크 지정
      - app-network

  # 2. 프론트엔드 서비스 정의
  frontend:
    build:
      context: ./frontend # frontend 디렉토리에서 Dockerfile을 찾아 빌드
      dockerfile: Dockerfile
    ports:
      - "3000:80" # 호스트의 3000번 포트를 컨테이너의 80번 포트에 매핑 (Nginx 기본 포트)
    volumes:
      - ./frontend:/app # 개발 중 소스 코드 변경을 위해 마운트 (Nginx가 아닌 개발 서버를 사용 시 필요)
      - /app/node_modules # node_modules는 호스트와 동기화하지 않음
    depends_on: # 백엔드 API 호출을 위해 백엔드 서비스가 먼저 시작되도록 설정 (선택 사항)
      - backend
    networks:
      - app-network

  # 3. 데이터베이스 서비스 정의 (PostgreSQL)
  db:
    image: postgres:13 # PostgreSQL 이미지 사용
    environment: # 데이터베이스 환경 변수 설정
      POSTGRES_DB: mydatabase
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - db-data:/var/lib/postgresql/data # 데이터 영속성을 위한 볼륨 마운트
    ports:
      - "5432:5432" # (선택 사항) 호스트에서 DB 클라이언트로 접속할 경우 포트 매핑
    networks:
      - app-network

# 4. 네트워크 정의
networks:
  app-network:
    driver: bridge # 기본 브릿지 네트워크 사용

# 5. 볼륨 정의
volumes:
  db-data: # PostgreSQL 데이터 저장을 위한 이름 있는 볼륨

각 섹션에 대한 자세한 설명은 다음과 같습니다.

  • version: '3.8': Docker Compose 파일의 문법 버전을 지정합니다. 최신 기능을 사용하려면 높은 버전을 지정하는 것이 좋습니다.
  • services:: 이 블록 아래에 각 컨테이너 서비스를 정의합니다.
  • backend, frontend, db: 각 서비스의 이름입니다. 이 이름은 같은 네트워크 내에서 컨테이너 간에 호스트명처럼 사용될 수 있습니다.
  • build:: 해당 서비스의 이미지를 빌드하는 방법을 정의합니다.
    • context: ./backend: Dockerfile을 찾을 경로를 지정합니다.
    • dockerfile: Dockerfile: 사용할 Dockerfile의 이름을 지정합니다 (기본값은 Dockerfile).
  • image: postgres:13: 이미 빌드된 Docker 이미지를 사용할 때 지정합니다. 여기서는 Docker Hub에서 postgres:13 이미지를 가져옵니다.
  • ports:: 호스트 머신의 포트와 컨테이너 내부의 포트를 매핑합니다. "호스트_포트:컨테이너_포트" 형식입니다.
  • volumes:: 데이터 영속성과 호스트-컨테이너 간 파일 공유를 위해 볼륨을 정의합니다.
    • ./backend:/app: 호스트의 backend 디렉토리를 컨테이너의 /app 디렉토리에 마운트하여 소스 코드 변경 시 컨테이너에 즉시 반영되도록 합니다.
    • /app/node_modules: 익명 볼륨으로, node_modules 디렉토리는 호스트와 동기화하지 않고 컨테이너 내부에 유지하도록 합니다. 이는 호스트 OS와 컨테이너 OS의 파일 시스템 차이로 인한 문제를 방지하고, 빌드 속도를 높이는 데 도움이 됩니다.
    • db-data:/var/lib/postgresql/data: 이름 있는 볼륨(Named Volume)을 사용하여 PostgreSQL의 데이터를 영구적으로 저장합니다. 컨테이너가 삭제되어도 데이터는 유지됩니다.
  • environment:: 컨테이너 내부에 설정할 환경 변수를 정의합니다. 데이터베이스 접속 정보나 API 키 등을 설정할 때 유용합니다.
  • depends_on:: 서비스 간의 의존성을 정의합니다. 예를 들어, backend 서비스가 시작되기 전에 db 서비스가 시작되도록 합니다. 이는 컨테이너 시작 순서만 보장하며, 서비스가 완전히 준비되었는지까지 보장하지는 않습니다.
  • networks:: 서비스가 사용할 네트워크를 지정합니다. 모든 서비스가 app-network를 사용하므로 서로 통신할 수 있습니다.
  • networks: (최하단 블록): 사용자 정의 네트워크를 정의합니다. driver: bridge는 가장 일반적인 브릿지 네트워크를 생성합니다.
  • volumes: (최하단 블록): 이름 있는 볼륨을 정의합니다. db-data:와 같이 이름을 지정하면 Docker가 해당 볼륨을 관리합니다.

환경 구축 및 실행

docker-compose.yml 파일과 각 서비스의 Dockerfile, 그리고 소스 코드가 준비되었다면, 프로젝트 최상위 디렉토리에서 다음 명령어를 실행하여 다중 서비스 개발 환경을 구축하고 시작할 수 있습니다.

docker compose up --build -d
  • up: docker-compose.yml 파일에 정의된 모든 서비스를 시작합니다.
  • --build: 이미지가 존재하지 않거나, Dockerfile이 변경되었을 경우 이미지를 다시 빌드합니다. 첫 실행 시 반드시 포함해야 합니다.
  • -d (detached mode): 컨테이너를 백그라운드에서 실행하고 터미널을 다시 사용할 수 있게 합니다.

명령어를 실행하면 Docker Compose가 각 서비스의 이미지를 빌드(또는 풀)하고, 컨테이너를 생성하여 실행합니다. 모든 서비스가 성공적으로 시작되면, 브라우저에서 http://localhost:3000으로 접속하여 프론트엔드 애플리케이션을 확인할 수 있습니다.

구축된 환경 효율적으로 관리하고 문제 해결하기

Docker Compose로 개발 환경을 구축한 후에도, 효율적인 관리가 중요합니다. 서비스를 모니터링하고, 필요에 따라 중지하거나 재시작하며, 발생할 수 있는 문제에 대응하는 방법을 알아봅시다.

주요 Docker Compose 명령어

  • 모든 서비스 시작 (백그라운드):
    docker compose up -d
  • 서비스 중지 및 컨테이너 제거:
    docker compose down
    ⚠️ -v 옵션을 추가하면 볼륨(db-data 등)까지 함께 제거되므로 주의해야 합니다. 데이터 손실을 원치 않는다면 사용하지 마세요.
  • docker compose down -v # 볼륨까지 함께 제거
  • 실행 중인 서비스 목록 확인:
    docker compose ps
  • 특정 서비스의 로그 확인:
    docker compose logs -f [서비스_이름]
    예: docker compose logs -f backend (-f는 follow 옵션으로 실시간 로그 확인)
  • 컨테이너 내부로 접속:
    docker compose exec [서비스_이름] bash
    예: docker compose exec backend bash (백엔드 컨테이너 내부 쉘 접속)
  • 이미지 다시 빌드:
    docker compose build [서비스_이름]
    예: docker compose build backend (백엔드 이미지만 다시 빌드)
    docker compose build --no-cache backend
  • --no-cache 옵션을 사용하면 캐시를 사용하지 않고 새로 빌드합니다.

일반적인 문제 해결 팁

  • 포트 충돌: "Address already in use" 에러가 발생하면, 호스트 머신에서 해당 포트를 이미 다른 애플리케이션이 사용 중이라는 의미입니다. docker-compose.yml 파일의 ports 설정을 변경하거나, 해당 포트를 사용하는 다른 애플리케이션을 종료해야 합니다.
  • 서비스 시작 실패: 특정 서비스가 시작되지 않는다면, 해당 서비스의 로그를 먼저 확인합니다 (docker compose logs [서비스_이름]). Dockerfile이나 애플리케이션 코드에 오류가 있을 수 있습니다.
  • 데이터베이스 연결 문제: 백엔드가 데이터베이스에 연결되지 못한다면,
    • docker-compose.ymldepends_on 설정이 올바른지 확인합니다.
    • 환경 변수(DATABASE_URL, POSTGRES_USER 등)가 정확한지 확인합니다.
    • 내부 네트워크에서 서비스 이름(db)이 올바르게 사용되었는지 확인합니다.
  • 소스 코드 변경 미반영: volumes 설정이 올바른지 확인합니다. ./backend:/app과 같이 호스트 경로가 컨테이너 경로에 정확히 마운트되어야 합니다. 또한, 컨테이너 내부에서 node_modules와 같은 빌드 산출물이 호스트와 동기화되지 않도록 익명 볼륨을 잘 설정했는지 확인합니다.

이러한 관리 및 문제 해결 팁을 숙지하면 Docker Compose를 활용한 개발 환경을 더욱 안정적으로 운영할 수 있습니다.

Docker Compose를 활용한 다중 서비스 로컬 개발 환경 구축 실전 가이드 - man, computer, screen, desktop, imac, apple products, desktop computer, workspace, workplace, working, technology, indoors, desk, office, information, display, monitor, programmer, developer, computer, computer, desktop, information, monitor, programmer, programmer, programmer, developer, developer, developer, developer, developer

Image by Pexels on Pixabay

더 나은 개발 경험을 위한 Docker Compose 고급 활용 팁

기본적인 환경 구축을 넘어, Docker Compose를 활용하여 개발 경험을 더욱 풍부하고 유연하게 만들 수 있는 몇 가지 고급 팁을 소개합니다.

이름 있는 볼륨(Named Volumes) 활용

앞서 PostgreSQL 데이터 저장을 위해 db-data라는 이름 있는 볼륨을 사용했습니다. 이름 있는 볼륨은 컨테이너 수명 주기와 독립적으로 데이터를 관리할 수 있어, 데이터 영속성이 필요한 경우에 매우 유용합니다. 예를 들어, 개발 중 데이터베이스를 초기화해야 할 때, 단순히 docker compose down -v를 실행하여 볼륨까지 삭제하고 새로 시작할 수 있습니다.

volumes:
  db-data:

이렇게 정의된 볼륨은 호스트의 특정 경로가 아닌 Docker가 관리하는 영역에 저장됩니다. docker volume ls 명령어로 관리 중인 볼륨 목록을 확인할 수 있습니다.

사용자 정의 네트워크(Custom Networks)

기본적으로 Docker Compose는 모든 서비스에 대해 단일 브릿지 네트워크를 생성합니다. 대부분의 경우 충분하지만, 복잡한 애플리케이션에서는 특정 서비스 그룹 간의 격리나 특별한 통신 규칙이 필요할 수 있습니다. 이때 사용자 정의 네트워크를 사용할 수 있습니다.

services:
  backend:
    # ...
    networks:
      - backend-network
      - shared-network

  frontend:
    # ...
    networks:
      - frontend-network
      - shared-network

  db:
    # ...
    networks:
      - backend-network

networks:
  backend-network:
    driver: bridge
  frontend-network:
    driver: bridge
  shared-network:
    driver: bridge

위 예시에서는 backend-network, frontend-network, shared-network 세 가지 네트워크를 정의했습니다. 백엔드와 데이터베이스는 backend-network를 통해 통신하고, 프론트엔드와 백엔드는 shared-network를 통해 통신할 수 있습니다. 이렇게 하면 네트워크 트래픽을 분리하고 보안을 강화하는 데 도움이 됩니다.

환경 변수 및 .env 파일 활용

민감한 정보(예: 데이터베이스 비밀번호, API 키)나 환경에 따라 달라지는 설정 값(예: 개발/운영 환경)은 docker-compose.yml 파일에 직접 하드코딩하는 것보다 환경 변수로 관리하는 것이 좋습니다. Docker Compose는 프로젝트 루트 디렉토리에 있는 .env 파일을 자동으로 로드합니다.

.env 파일 예시:

# .env 파일
DB_USER=dev_user
DB_PASSWORD=dev_password
DB_NAME=dev_database
BACKEND_PORT=5000
FRONTEND_PORT=3000

docker-compose.yml 파일에서 이 환경 변수들을 참조할 수 있습니다.

services:
  backend:
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    ports:
      - "${BACKEND_PORT}:${BACKEND_PORT}"
  frontend:
    ports:
      - "${FRONTEND_PORT}:80"
  db:
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}

이렇게 하면 .env 파일만 수정하여 환경 설정을 쉽게 변경할 수 있으며, 민감한 정보는 Git에 커밋하지 않고 관리할 수 있습니다.

여러 Docker Compose 파일 사용

개발, 테스트, 배포 등 목적에 따라 Docker Compose 설정을 다르게 하고 싶을 때, 여러 개의 docker-compose.yml 파일을 사용할 수 있습니다. 예를 들어, 개발 환경에서는 볼륨 마운트를 통해 실시간 코드 변경을 반영하고, 운영 환경에서는 빌드된 이미지를 사용하며 리소스 제한을 설정할 수 있습니다.

  • docker-compose.yml: 기본 설정
  • docker-compose.dev.yml: 개발 환경에 특화된 설정 (예: 볼륨 마운트, 디버깅 포트)
  • docker-compose.prod.yml: 운영 환경에 특화된 설정 (예: 리소스 제한, Nginx 프록시)

여러 파일을 함께 사용하려면 -f 옵션을 사용합니다.

docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d

뒤에 오는 파일의 설정이 앞 파일의 설정을 덮어쓰거나 확장하는 방식으로 동작합니다. 이를 통해 유연하고 재사용 가능한 Docker Compose 설정을 만들 수 있습니다.

결론: Docker Compose로 개발 생산성을 극대화하세요

이 가이드를 통해 Docker Compose가 복잡한 다중 서비스 로컬 개발 환경을 얼마나 간단하고 효율적으로 만들어주는지 실감하셨기를 바랍니다. 더 이상 각 서비스의 런타임 버전이나 환경 설정 문제로 씨름할 필요가 없습니다. Docker Compose는 일관된 개발 환경, 빠른 온보딩, 그리고 간편한 서비스 관리라는 강력한 이점을 제공하여 개발자의 생산성을 혁신적으로 향상시킵니다.

우리는 백엔드(Node.js), 프론트엔드(React), 데이터베이스(PostgreSQL) 서비스를 포함하는 실전 예제를 통해 Dockerfile 작성부터 docker-compose.yml 파일 구성, 그리고 환경 관리 및 문제 해결 팁까지 상세히 살펴보았습니다. 또한, 이름 있는 볼륨, 사용자 정의 네트워크, .env 파일 활용, 여러 Compose 파일 사용 등 고급 팁들을 통해 더욱 유연하고 강력한 개발 환경을 구축하는 방법도 익혔습니다.

이제 여러분은 Docker Compose를 활용하여 어떤 규모의 다중 서비스 프로젝트라도 자신 있게 시작하고 관리할 수 있는 기반을 마련했습니다. 환경 설정에 드는 시간을 최소화하고, 핵심 비즈니스 로직 개발에 집중하여 더 많은 가치를 창출하세요. 이 가이드가 여러분의 개발 여정에 큰 도움이 되었기를 바랍니다.

혹시 Docker Compose를 활용한 다중 서비스 환경 구축 과정에서 추가로 궁금한 점이나 공유하고 싶은 팁이 있으신가요? 댓글로 자유롭게 의견을 남겨주시면 감사하겠습니다!

📌 함께 읽으면 좋은 글

  • [이슈 분석] 플랫폼 엔지니어링 도입, 개발 조직 문화와 데브옵스 역할 변화 핵심 분석
  • [튜토리얼] Docker Compose Nginx Node.js PostgreSQL 로컬 개발 환경 구축: 실전 가이드
  • [튜토리얼] Node.js Apollo Server GraphQL API 구축: 개발자를 위한 실전 가이드

이 글이 도움이 되셨다면 공감(♥)댓글로 응원해 주세요!
궁금한 점이나 다루었으면 하는 주제가 있다면 댓글로 남겨주세요.

반응형