🎯 학습 목표
- docker compose로 여러 컨테이너를 한 번에 정의·실행한다.
- Spring Boot가 컨테이너 이름으로 MySQL에 접속하도록 연결한다.
depends_on과 헬스체크로 실행 순서를 제어한다.
📖 개념 설명
지금까지는 컨테이너를 하나씩 docker run으로 띄웠습니다. 실제 앱은 보통 “앱 + DB(+캐시…)”가 함께 떠야 합니다. docker compose는 이 구성을 compose.yaml 파일 하나에 선언하고 docker compose up 한 번으로 전부 띄워 줍니다.
compose가 자동으로 만드는 네트워크 안에서는 서비스 이름이 곧 호스트명이 됩니다. 즉 Spring Boot에서 DB 주소를 localhost가 아니라 db(서비스 이름)로 적어야 컨테이너끼리 통신됩니다. 초보자가 가장 많이 틀리는 지점입니다.
💻 compose.yaml
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpw
MYSQL_DATABASE: appdb
MYSQL_USER: appuser
MYSQL_PASSWORD: apppw
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-prootpw"]
interval: 5s
timeout: 3s
retries: 10
app:
build: . # 같은 폴더의 Dockerfile로 빌드
ports:
- "8080:8080"
environment:
# 핵심: host를 'db'(서비스 이름)로! localhost 아님
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/appdb
SPRING_DATASOURCE_USERNAME: appuser
SPRING_DATASOURCE_PASSWORD: apppw
depends_on:
db:
condition: service_healthy # DB가 준비된 뒤 앱 시작
volumes:
mysql_data:
💻 Spring Boot 쪽 설정 (application.yml)
# 환경변수로 덮어쓰므로 기본값만 둬도 됨
spring:
datasource:
url: jdbc:mysql://localhost:3306/appdb
username: appuser
password: apppw
jpa:
hibernate:
ddl-auto: update # 학습용. 운영은 flyway/liquibase 권장
💻 실행 & 관리
# 빌드 + 전체 실행 (백그라운드)
docker compose up -d --build
# 상태 / 로그
docker compose ps
docker compose logs -f app
# 동작 확인
curl http://localhost:8080/hello
# 전체 중지 + 컨테이너 제거 (볼륨은 유지)
docker compose down
# 볼륨까지 완전 삭제 (DB 데이터도 지워짐)
docker compose down -v
⚠️ 주의사항
- DB 주소는 반드시 서비스 이름(
db)으로.localhost로 두면 “앱 컨테이너 자신”을 가리켜 연결 실패합니다. - DB가 아직 준비 전인데 앱이 먼저 떠서 연결 실패하면
healthcheck+condition: service_healthy로 순서를 잡으세요. - 비밀번호는
.env파일로 분리하고.gitignore에 추가하세요.
💡 팁
docker compose up(–d 없이)으로 포그라운드 실행하면 로그를 바로 보며 디버깅하기 좋습니다.- 앱 코드만 바꿨다면
docker compose up -d --build app으로 app 서비스만 재빌드할 수 있습니다. - 이 구성이 곧 운영 배포의 축소판입니다. 같은 compose를 서버에 올리면 거의 그대로 동작합니다.