반응형
0: 개요
Docker Compose를 활용해 로컬 개발 환경을 몇 분 만에 구성하는 방법을 설명합니다. 백엔드/프론트엔드/DB/캐시를 한 번에 올리는 Compose 예제, .env 관리, 볼륨/네트워크, healthcheck & depends_on, 프로파일(profiles), 오버라이드 파일, 핫 리로드, 트러블슈팅까지 실무 포인트를 담았습니다.1. 왜 Docker Compose인가?
- 원클릭(원커맨드) 부팅:
docker compose up -d한 번으로 모든 서비스 실행 - 개발-테스트 일관성: 팀원/CI 환경이 동일한 스택 사용
- 격리된 네트워크: 서비스명으로 안정적 통신(
DB_HOST=mysql) - 빠른 재현: 버그 재현/시나리오 테스트에 최적
2. 핵심 개념 한눈에
| 개념 | 설명 | 예시 |
|---|---|---|
| services | 컨테이너 집합 | backend, frontend, mysql, redis |
| volumes | 데이터/코드 공유 | .:/app, db-data:/var/lib/mysql |
| networks | 컨테이너 간 DNS | 서비스명으로 통신(mysql:3306) |
| env | 환경 변수/비밀 관리 | .env, environment: |
| healthcheck | 준비 상태 판단 | mysqladmin ping |
| depends_on | 기동 순서/대기 | condition: service_healthy |
| profiles | 선택적 서비스 | profiles: [dev] |
3. 5분 만에 끝내는 빠른 시작 (백엔드+프론트+MySQL+Redis)
1) 폴더 구조
project/
├─ docker-compose.yml
├─ .env
├─ backend/ # Spring Boot or Node.js
├─ frontend/ # React/Vite/Next
└─ init/ # DB 초기 스키마/더미 데이터(sql)
2) .env (개발용)
MYSQL_DATABASE=appdb
MYSQL_USER=appuser
MYSQL_PASSWORD=apppass
MYSQL_ROOT_PASSWORD=rootpass
DB_HOST=mysql
DB_PORT=3306
REDIS_HOST=redis
REDIS_PORT=6379
BACKEND_PORT=8080
FRONTEND_PORT=5173
3) docker-compose.yml
version: "3.8"
services:
mysql:
image: mysql:8.0
container_name: mysql
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
ports: ["3306:3306"]
volumes:
- db-data:/var/lib/mysql
- ./init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p$$MYSQL_ROOT_PASSWORD --silent"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
networks: [app-net]
redis:
image: redis:7-alpine
container_name: redis
ports: ["6379:6379"]
command: ["redis-server", "--appendonly", "yes"]
networks: [app-net]
backend:
build: ./backend
container_name: backend
ports: ["${BACKEND_PORT}:8080"]
environment:
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_NAME: ${MYSQL_DATABASE}
DB_USER: ${MYSQL_USER}
DB_PASSWORD: ${MYSQL_PASSWORD}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
volumes:
- ./backend:/app
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
networks: [app-net]
frontend:
build: ./frontend
container_name: frontend
ports: ["${FRONTEND_PORT}:5173"]
environment:
VITE_API_URL: http://localhost:${BACKEND_PORT}
volumes:
- ./frontend:/app
depends_on:
backend:
condition: service_started
networks: [app-net]
profiles: ["dev"] # 필요할 때만 올리기
volumes:
db-data:
networks:
app-net:
driver: bridge
실행: docker compose up -d → 백엔드(http://localhost:8080), 프론트(http://localhost:5173)
4. 코드 변경 즉시 반영: 핫 리로드
- Node.js:
nodemon또는tsx --watch사용,volumes로 소스 마운트 - Spring Boot:
spring-boot-devtools추가 + IDE 자동 빌드, 또는 JRebel - React/Vite:
vitedev 서버 실행,volumes마운트
예) Node.js Dockerfile (개발용)
# backend/Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 8080
CMD ["npm", "run", "dev"] # nodemon / tsx watch
예) Spring Boot Dockerfile (개발용)
# backend/Dockerfile
FROM eclipse-temurin:21-jdk
WORKDIR /app
COPY .mvn .mvn
COPY mvnw pom.xml ./
RUN ./mvnw -q -DskipTests dependency:go-offline
COPY src ./src
EXPOSE 8080
CMD ["./mvnw", "spring-boot:run", "-Dspring-boot.run.profiles=local"]
5. Healthcheck & depends_on로 안정 부팅
DB가 준비되기 전에 앱이 먼저 올라오면 연결 실패가 납니다. healthcheck와 depends_on: condition: service_healthy를 사용하면 앱이 DB 준비를 기다립니다.
depends_on:
mysql:
condition: service_healthy
6. profiles / override 파일로 유연하게
1) profiles
# 특정 서비스만 선택적으로 기동
docker compose --profile dev up -d
docker compose --profile dev down
2) override 파일
docker-compose.override.yml은 자동 병합됩니다(로컬 개발 전용 설정 등).
# docker-compose.override.yml (예시)
services:
backend:
environment:
LOG_LEVEL: debug
extra_hosts:
- "host.docker.internal:host-gateway"
7. 유용한 명령 모음
# 상태/로그/셸
docker compose ps
docker compose logs -f backend
docker compose exec mysql bash
# 정리
docker compose down -v # 볼륨 포함 제거(주의!)
docker system prune -af # 강력 정리(신중히)
8. 트러블슈팅 체크리스트
- 연결 안 됨: 서비스명으로 접근했는지 확인 (
DB_HOST=mysql,localhost금지) - DB 준비 전 앱 기동: healthcheck & depends_on 설정
- .env 적용 안 됨:
docker compose config로 실제 값 확인 - 포트 충돌:
lsof -i :포트로 점유 확인 후 변경 - 파일 변경 미반영:
volumes마운트/감시 도구 설정(nodemon/devtools) 확인
9. 캐시/속도 최적화 (빌드 및 런타임)
- Dockerfile 계층 최적화: 의존성 설치를 소스 복사 전에 실행(
package.json→npm ci→COPY . .) - 멀티스테이지: 빌드와 런타임 이미지를 분리해 용량↓
- 볼륨 전략: DB 데이터는 네임드 볼륨 사용(
db-data) - 공유 네트워크: 팀/다른 compose와 통신이 필요하면 사전에
docker network create로 외부 네트워크 구성
10. 보너스: Makefile로 원커맨드 자동화
up:
\tdocker compose up -d
down:
\tdocker compose down
logs:
\tdocker compose logs -f --tail=200
rebuild:
\tdocker compose build --no-cache && docker compose up -d
11. 요약
- Compose로 DB/캐시/백엔드/프론트를 한 번에 올린다
- .env로 환경 변수 표준화, volumes로 핫 리로드
- healthcheck + depends_on으로 안정된 부팅
- profiles/override로 상황별 구성 제어
한 줄 정리: “docker compose up -d” 한 번으로 팀 전체 개발 환경을 일관되게!
반응형
'Backend > Study' 카테고리의 다른 글
| [DevOps] AWS EC2와 RDS 연결 설정 가이드 (0) | 2025.10.21 |
|---|---|
| [DevOps] 서버 비용 절감하는 클라우드 아키텍처 설계법 (0) | 2025.10.20 |
| [DevOps] 클라우드 모니터링 도구 비교 (Datadog, Prometheus, Grafana) (0) | 2025.10.16 |
| [Tip] 실무에서 자주 쓰는 SQL 최적화 패턴 10가지 (0) | 2025.10.15 |
| [Study] 백엔드 로그 관리 전략 (ELK, Loki, Grafana) (0) | 2025.10.14 |