Docker Compose로 개발 환경 표준화: "내 컴퓨터에선 되는데" 끝내기

마이크로서비스(MSA) 환경에서 여러 개발자가 동시에 작업하다 보면 로컬 개발 환경 불일치 문제가 반드시 발생합니다. "내 컴퓨터에선 되는데요?"라는 말이 코드 리뷰에서 나온다면, 그건 환경 문제입니다. 저희 팀은 이 문제를 해결하기 위해 Docker Compose 기반 개발 환경 표준화를 도입했습니다.

문제 상황

MSA 환경에서 흔히 겪는 어려움:

  • 개발자 A는 macOS + Node 18, 개발자 B는 Windows + Node 16
  • PostgreSQL 버전이 달라 특정 쿼리가 동작하지 않음
  • Redis 설정이 로컬마다 다름
  • 새 개발자 온보딩에 반나절 이상 소요

결과적으로 버그 재현, 테스트, 코드 리뷰 과정에서 불필요한 혼란이 발생했습니다.

Docker Compose 기본 구성

Docker Compose를 이용하면 여러 서비스를 단일 명령어로 구성할 수 있습니다:

YAML
# docker-compose.yml
version: "3.8"

services:
  # PostgreSQL 데이터베이스
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: ${DB_USER:-dev}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-devpass}
      POSTGRES_DB: ${DB_NAME:-myapp}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./scripts/init.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-dev}"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis 캐시
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Elasticsearch (검색)
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - es_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"

  # 메인 애플리케이션
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgresql://${DB_USER:-dev}:${DB_PASSWORD:-devpass}@postgres:5432/${DB_NAME:-myapp}
      - REDIS_URL=redis://redis:6379
      - ELASTICSEARCH_URL=http://elasticsearch:9200
    volumes:
      - .:/app
      - /app/node_modules  # node_modules 격리
    ports:
      - "3000:3000"
      - "9229:9229"  # 디버거 포트
    command: npm run dev

volumes:
  postgres_data:
  redis_data:
  es_data:

환경별 설정 분리

개발, 테스트, CI 환경을 분리하여 관리합니다:

YAML
# docker-compose.override.yml (개발용 - 자동 로드)
version: "3.8"
services:
  app:
    volumes:
      - .:/app
    environment:
      - DEBUG=true
      - LOG_LEVEL=debug

---
# docker-compose.test.yml (테스트용)
version: "3.8"
services:
  postgres:
    tmpfs: /var/lib/postgresql/data  # 메모리 DB로 빠른 테스트

  app:
    environment:
      - NODE_ENV=test
    command: npm test

---
# docker-compose.ci.yml (CI/CD용)
version: "3.8"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.ci
    environment:
      - CI=true

실행 명령어

BASH
# 개발 환경 시작
docker compose up -d

# 테스트 실행
docker compose -f docker-compose.yml -f docker-compose.test.yml up --abort-on-container-exit

# CI 환경
docker compose -f docker-compose.yml -f docker-compose.ci.yml up

개발 생산성 향상 팁

1. 핫 리로드 설정

DOCKERFILE
# Dockerfile.dev
FROM node:20-alpine

WORKDIR /app

# 의존성 먼저 설치 (캐싱 최적화)
COPY package*.json ./
RUN npm ci

# 소스 코드는 볼륨 마운트로 처리
# COPY . .  # 개발용에선 불필요

CMD ["npm", "run", "dev"]

2. 데이터 시드 자동화

SQL
# scripts/init.sql
-- 개발용 초기 데이터
INSERT INTO users (email, name, role) VALUES
  ('admin@dev.local', 'Admin', 'admin'),
  ('user@dev.local', 'Test User', 'user');

INSERT INTO settings (key, value) VALUES
  ('feature_new_ui', 'true'),
  ('maintenance_mode', 'false');

3. 편리한 명령어 스크립트

MAKEFILE
# Makefile
.PHONY: up down logs shell db-shell reset

up:
	docker compose up -d
	@echo "서비스 시작됨: http://localhost:3000"

down:
	docker compose down

logs:
	docker compose logs -f app

shell:
	docker compose exec app sh

db-shell:
	docker compose exec postgres psql -U dev -d myapp

reset:
	docker compose down -v
	docker compose up -d
	@echo "데이터 초기화 완료"

트러블슈팅

문제 1: 포트 충돌

YAML
# .env 파일로 포트 커스터마이징
DB_PORT=5433
REDIS_PORT=6380
APP_PORT=3001

# docker-compose.yml에서 참조
ports:
  - "${DB_PORT:-5432}:5432"

문제 2: 볼륨 권한 이슈 (Linux)

DOCKERFILE
# Dockerfile.dev
ARG UID=1000
ARG GID=1000
RUN addgroup -g $GID appgroup && adduser -u $UID -G appgroup -D appuser
USER appuser

문제 3: Apple Silicon (M1/M2) 호환성

YAML
services:
  postgres:
    platform: linux/amd64  # x86 이미지 강제 사용
    # 또는 ARM 네이티브 이미지 사용
    image: arm64v8/postgres:15

도입 성과

Docker Compose 기반 환경 표준화 후 변화:

지표이전이후
신규 개발자 온보딩4시간15분
"내 컴에선 됨" 이슈주 3회0회
환경 설정 문서20페이지README 1페이지
CI 환경 차이 버그월 5건월 0건

"docker compose up 한 번이면 개발 시작" - 이것이 우리의 목표였고, 달성했습니다.


 

도커 docker