본문 바로가기
Web/Backend

Docker Compose로 개발 환경 5분 만에 세팅하기

by 태균맨 2026. 3. 24.
반응형

새 프로젝트를 시작할 때마다 개발 환경 세팅에 반나절을 쓰고 있지 않은가? PostgreSQL 설치하고, Redis 띄우고, 환경 변수 맞추고... 팀원이 합류할 때마다 같은 과정을 반복한다. Docker Compose를 쓰면 이 모든 과정을 5분으로 줄일 수 있다.

이 글은 Docker Compose를 처음 접하는 개발자도 따라 할 수 있게 단계별로 정리했다. 실제 웹 애플리케이션 개발에서 자주 쓰는 구성을 기준으로 설명한다.

준비물 확인

시작하기 전에 아래 항목을 확인하자.

  • 운영체제: Windows 10/11, macOS, Linux 모두 가능
  • 디스크 여유 공간: 최소 5GB (Docker 이미지 저장용)
  • RAM: 최소 4GB, 권장 8GB 이상
  • 터미널 기본 사용법: cd, ls 정도는 알아야 한다

Docker나 컨테이너 개념을 몰라도 괜찮다. 지금부터 필요한 만큼만 설명한다.

1단계: Docker Desktop 설치

Docker Desktop 공식 사이트에서 본인 운영체제에 맞는 버전을 다운로드한다.

macOS 사용자 주의사항: Apple Silicon(M1/M2/M3/M4) 맥이라면 "Apple Silicon" 버전을 선택해야 한다. Intel 버전을 설치하면 Rosetta 에뮬레이션으로 돌아가서 성능이 크게 떨어진다.

Windows 사용자 주의사항: WSL 2 백엔드를 활성화해야 한다. Docker Desktop 설치 과정에서 안내가 나오니 따라 하면 된다.

설치 후 터미널에서 확인한다.

docker --version
# Docker version 27.x.x

docker compose version
# Docker Compose version v2.x.x

두 명령어 모두 버전이 출력되면 준비 완료다.

2단계: docker-compose.yml 작성

프로젝트 루트에 docker-compose.yml 파일을 만든다. 아래는 Node.js + PostgreSQL + Redis 조합의 실전 예시다. 내가 실제 프로젝트에서 쓰는 구성을 기반으로 작성했다.

services:
  db:
    image: postgres:16-alpine
    container_name: myapp-db
    restart: unless-stopped
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: ${DB_USER:-devuser}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-devpass}
      POSTGRES_DB: ${DB_NAME:-myapp}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-devuser}"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: myapp-redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 5s
      retries: 5

  mailhog:
    image: mailhog/mailhog:latest
    container_name: myapp-mail
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI

volumes:
  postgres_data:
  redis_data:

각 서비스를 간단히 설명하면 다음과 같다.

  • db: PostgreSQL 16 데이터베이스. Alpine 이미지를 쓰면 용량이 작다.
  • redis: 캐싱, 세션 저장, 큐 등에 사용하는 인메모리 저장소.
  • mailhog: 개발용 이메일 서버. 실제로 메일을 보내지 않고 웹 UI에서 확인할 수 있다.

healthcheck를 넣은 이유는 서비스가 실제로 준비됐는지 확인하기 위해서다. 이게 없으면 컨테이너는 떴는데 DB 연결이 안 되는 타이밍 이슈가 생긴다.

3단계: 환경 변수 설정

프로젝트 루트에 .env 파일을 만든다.

# .env
DB_USER=devuser
DB_PASSWORD=devpass
DB_NAME=myapp
DB_HOST=localhost
DB_PORT=5432

REDIS_HOST=localhost
REDIS_PORT=6379

MAIL_HOST=localhost
MAIL_PORT=1025

그리고 .env.example 파일도 함께 만들어서 Git에 커밋한다. 실제 값 대신 설명을 넣는다.

# .env.example
DB_USER=devuser
DB_PASSWORD=devpass
DB_NAME=myapp
DB_HOST=localhost
DB_PORT=5432

REDIS_HOST=localhost
REDIS_PORT=6379

MAIL_HOST=localhost
MAIL_PORT=1025

중요: .env 파일은 반드시 .gitignore에 추가한다. 실수로 커밋하면 보안 사고가 발생할 수 있다.

4단계: 실행 및 확인

터미널에서 프로젝트 루트로 이동한 뒤 실행한다.

# 모든 서비스 백그라운드로 실행
docker compose up -d

# 상태 확인
docker compose ps

# 로그 확인 (전체)
docker compose logs

# 특정 서비스 로그만 보기
docker compose logs -f db

정상적으로 실행되면 아래와 같이 확인할 수 있다.

  • PostgreSQL: psql -h localhost -U devuser -d myapp 또는 DBeaver 등 GUI 툴로 접속
  • Redis: redis-cli ping → PONG 응답
  • MailHog: 브라우저에서 http://localhost:8025 접속

5단계: 개발 워크플로우 세팅

매번 수동으로 명령어를 입력하지 않도록 package.json에 스크립트를 추가한다.

{
  "scripts": {
    "infra:up": "docker compose up -d",
    "infra:down": "docker compose down",
    "infra:reset": "docker compose down -v && docker compose up -d",
    "infra:logs": "docker compose logs -f",
    "dev": "npm run infra:up && npm run start:dev"
  }
}

npm run dev 하나로 인프라 실행과 개발 서버 시작이 동시에 된다. infra:reset은 볼륨까지 삭제하고 깨끗하게 다시 시작할 때 쓴다. DB 데이터를 초기화하고 싶을 때 유용하다.

실무에서 유용한 팁 3가지

팁 1: 초기 데이터 자동 세팅

PostgreSQL 이미지는 /docker-entrypoint-initdb.d/ 폴더의 SQL 파일을 자동 실행한다. 프로젝트에 init.sql을 만들어두면 컨테이너가 처음 생성될 때 테이블과 시드 데이터가 자동으로 세팅된다.

-- init.sql
CREATE TABLE IF NOT EXISTS users (
  id SERIAL PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  name VARCHAR(100) NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

INSERT INTO users (email, name) VALUES
  ('admin@example.com', 'Admin'),
  ('test@example.com', 'Test User');

팁 2: 볼륨으로 데이터 유지

docker compose down을 해도 volumes에 정의된 데이터는 유지된다. DB를 완전히 초기화하고 싶을 때만 docker compose down -v를 쓴다. 이 차이를 모르면 "데이터가 왜 사라졌지?" 또는 "왜 안 사라지지?" 하는 혼란이 생긴다.

팁 3: 여러 프로젝트 동시 운영

포트 충돌을 피하려면 프로젝트별로 포트를 다르게 설정한다. 환경 변수로 포트를 관리하면 편하다.

# 프로젝트 A
DB_PORT=5432

# 프로젝트 B
DB_PORT=5433

자주 발생하는 문제와 해결법

Q: "port is already allocated" 에러가 뜬다.

A: 해당 포트를 이미 다른 프로세스가 쓰고 있다. lsof -i :5432로 확인하고, 기존 프로세스를 종료하거나 docker-compose.yml에서 포트를 변경한다.

Q: 컨테이너가 계속 재시작된다.

A: docker compose logs 서비스명으로 에러 로그를 확인한다. 대부분 환경 변수 누락이나 설정 오류다.

Q: DB에 연결이 안 된다.

A: healthcheck 상태를 확인한다. docker compose ps에서 해당 서비스가 "healthy" 상태인지 본다. 아직 "starting" 상태라면 잠시 기다리면 된다.

Q: Mac에서 너무 느리다.

A: Docker Desktop 설정에서 리소스 할당을 확인한다. 또한 볼륨 마운트 성능이 느릴 수 있으니, 코드는 로컬에서 실행하고 DB만 Docker로 띄우는 하이브리드 방식을 추천한다. 위에서 소개한 구성이 바로 이 방식이다.

Docker Compose는 한번 세팅해두면 팀 전체가 동일한 개발 환경을 공유할 수 있다. 새 팀원이 합류해도 git clonenpm run dev 두 줄이면 개발을 시작할 수 있다. 아직 로컬에 직접 DB를 설치해서 쓰고 있다면, 이번 주말에 Docker Compose로 전환해보자. 투자 대비 효과가 확실한 개선이다.

반응형

'Web > Backend' 카테고리의 다른 글

Prisma 시작하기  (0) 2025.06.25