Docker Compose로 전체 스택을 실행하고 효과적으로 관리.
# 프로젝트 루트로 이동
cd ~/Desktop/DevCource_2
# 백그라운드 실행 (처음 실행)
docker-compose up -d
# 빌드 + 실행 (소스 변경 시)
docker-compose up --build -d
# 포그라운드 실행 (로그 실시간 확인)
docker-compose up
# 프로젝트 루트로 이동
cd C:\Users\YourName\Desktop\DevCource_2
# 백그라운드 실행
docker-compose up -d
# 빌드 + 실행
docker-compose up --build -d
docker-compose up --build -d 실행 시:
[1단계] 이미지 확인 및 빌드 (2-5분)
├─ MySQL 이미지 확인 (로컬에 있으면 재사용)
├─ Redis 이미지 확인 (로컬에 있으면 재사용)
└─ Spring Boot 이미지 빌드
├─ Gradle 의존성 다운로드 (60초)
├─ bootJar 빌드 (50초)
└─ Docker 이미지 생성 (20초)
[2단계] 컨테이너 생성 및 시작 (30-60초)
├─ MySQL 컨테이너 시작
│ ├─ 데이터베이스 초기화
│ └─ Healthcheck 대기 (30초)
├─ Redis 컨테이너 시작
│ ├─ 메모리 할당
│ └─ Healthcheck 대기 (5초)
└─ Spring Boot 컨테이너 시작
├─ MySQL/Redis healthy 대기
├─ 애플리케이션 시작
└─ BaseInitData 실행 (초기 데이터 생성)
[3단계] 완료
✅ 3개 컨테이너 모두 healthy 상태
| 상황 | 소요 시간 |
|---|---|
| 첫 실행 | 3-5분 (이미지 다운로드 + 빌드) |
| 재실행 (이미지 있음) | 1-2분 (빌드만) |
| 재시작 (컨테이너 있음) | 30초-1분 |
| 코드만 수정 | 1-2분 (app만 재빌드) |
# 컨테이너 목록 및 상태
docker-compose ps
# 출력 예시:
NAME IMAGE STATUS PORTS
auction-app devcource_2-app Up 2 min (healthy) 0.0.0.0:8080->8080/tcp
auction-mysql-compose mysql:8.0 Up 3 min (healthy) 0.0.0.0:3307->3306/tcp
auction-redis-compose redis:7-alpine Up 3 min (healthy) 0.0.0.0:6380->6379/tcp
확인 포인트:
Up + (healthy) 상태# 전체 헬스 상태
docker ps --format "table {{.Names}}\t{{.Status}}"
# 출력 예시:
NAMES STATUS
auction-app Up 5 minutes (healthy)
auction-mysql-compose Up 5 minutes (healthy)
auction-redis-compose Up 5 minutes (healthy)
# 실시간 리소스 사용량
docker stats
# 출력 예시:
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O
auction-app 5.23% 450MiB / 980MiB 45.92% 1.2MB / 800kB
auction-mysql-compose 2.15% 620MiB / 980MiB 63.27% 800kB / 1.2MB
auction-redis-compose 0.84% 12MiB / 510MiB 2.35% 500kB / 400kB
확인 포인트:
# 한 번만 출력
docker stats --no-stream
# 특정 컨테이너만
docker stats auction-app --no-stream
# 컨테이너 상세 정보 (JSON)
docker inspect auction-app
# 네트워크 정보만 확인
docker inspect auction-app | grep -A 20 NetworkSettings
# 리소스 제한 확인
docker inspect auction-app | grep -A 10 Memory
# 전체 컨테이너 로그 (실시간)
docker-compose logs -f
# 마지막 100줄만 보고 실시간 추적
docker-compose logs -f --tail=100
# 타임스탬프 포함
docker-compose logs -f -t
# Spring Boot 로그만
docker-compose logs -f app
# MySQL 로그만
docker-compose logs -f mysql
# Redis 로그만
docker-compose logs -f redis
# 특정 키워드 검색
docker-compose logs app | grep ERROR
docker-compose logs app | grep "BaseInitData"
docker-compose logs app | grep -i "hikari"
# 최근 1시간 로그
docker-compose logs --since 1h app
# 특정 시간 이후 로그
docker-compose logs --since 2026-01-28T10:00:00 app
docker-compose logs app | grep -i "baseinitdata"
# 출력 예시:
auction-app | BaseInitData 시작
auction-app | 카테고리 12개 생성 완료
auction-app | 테스트 유저 3명 생성 완료
auction-app | 테스트 경매 20개 생성 완료
docker-compose logs app | grep -i hikari
# 출력 예시:
HikariPool-1 - Starting...
HikariPool-1 - Added connection conn0: url=jdbc:mysql://mysql:3306/DevCourse
HikariPool-1 - Start completed.
docker-compose logs app | grep -i redis
# 출력 예시:
Lettuce ConnectionFactory initialized
# 모든 에러 로그
docker-compose logs app | grep -E "ERROR|WARN"
# 최근 에러만
docker-compose logs --tail=50 app | grep ERROR
# 로그를 파일로 저장
docker-compose logs app > app.log
# 모든 컨테이너 로그 저장
docker-compose logs > all.log
# 압축하여 저장
docker-compose logs | gzip > logs_$(date +%Y%m%d).log.gz
# 모든 컨테이너 재시작
docker-compose restart
# 출력 예시:
Restarting auction-app ... done
Restarting auction-mysql-compose ... done
Restarting auction-redis-compose ... done
# Spring Boot만 재시작
docker-compose restart app
# MySQL만 재시작
docker-compose restart mysql
# Redis만 재시작
docker-compose restart redis
# 컨테이너 중지 (삭제 안 함)
docker-compose stop
# 특정 컨테이너만 중지
docker-compose stop app
특징:
docker-compose start로 재시작 가능# 컨테이너 삭제 (Volume은 유지)
docker-compose down
# 출력 예시:
Stopping auction-app ... done
Stopping auction-mysql-compose ... done
Stopping auction-redis-compose ... done
Removing auction-app ... done
Removing auction-mysql-compose ... done
Removing auction-redis-compose ... done
Removing network devcource_2_auction-network
특징:
docker-compose up으로 재생성 시 데이터 그대로# 컨테이너 + Volume 모두 삭제
docker-compose down -v
# 경고 메시지:
# Removing volume mysql-compose-data
# Removing volume redis-compose-data
# Removing volume uploads-data
주의:
| 명령어 | 컨테이너 | Volume | 용도 |
|---|---|---|---|
docker-compose stop | 중지 (남음) | 유지 | 일시 중지 |
docker-compose down | 삭제 | 유지 | 정상 종료 |
docker-compose down -v | 삭제 | 삭제 | 완전 초기화 |
# Spring Boot만 재빌드 + 재시작
docker-compose build app
docker-compose up -d app
# 또는 한 줄로
docker-compose up -d --build app
소요 시간: 1-2분
# 모든 서비스 재빌드
docker-compose up --build -d
# 캐시 없이 완전 재빌드 (문제 발생 시)
docker-compose build --no-cache
docker-compose up -d
소요 시간: 3-5분
# 설정 파일 변경 시 (환경 변수, 포트 등)
docker-compose down
docker-compose up -d
# Dockerfile 변경 시 캐시 무효화
docker-compose build --no-cache app
docker-compose up -d app
# 1. 컨테이너 상태 확인
docker-compose ps
# 2. 재빌드
docker-compose build app
# 3. 재시작
docker-compose up -d app
# 4. 로그 확인
docker-compose logs -f app
# 5. 헬스체크
curl http://localhost:8080/actuator/health
Connection Name: Docker Compose MySQL
Hostname: localhost
Port: 3307 ← 중요! (3306 아님)
Username: root
Password: lldj123414
Default Schema: DevCourse
# MySQL CLI 접속
docker exec -it auction-mysql-compose mysql -u root -p
# 비밀번호 입력: lldj123414
자주 사용하는 명령:
-- 데이터베이스 선택
USE DevCourse;
-- 테이블 목록
SHOW TABLES;
-- 경매 조회
SELECT id, name, start_price, status FROM auctions LIMIT 10;
-- 유저 조회
SELECT id, username, nickname FROM users;
-- 입찰 조회
SELECT b.id, b.auction_id, b.price, u.nickname
FROM bids b JOIN users u ON b.bidder_id = u.id
LIMIT 10;
-- 종료
exit;
# Redis CLI 접속
docker exec -it auction-redis-compose redis-cli
자주 사용하는 명령:
# 127.0.0.1:6379> 프롬프트
# 모든 키 확인
KEYS *
# 경매 캐시 조회
GET auction::1
GET auction::2
# 캐시 통계
INFO stats
# 메모리 사용량
INFO memory
# 키 개수
DBSIZE
# 특정 패턴 검색
KEYS auction::*
# 캐시 삭제
DEL auction::1
# 전체 캐시 삭제 (주의!)
FLUSHALL
# 종료
exit
# Redis Insight 설치 (한 번만)
brew install --cask redisinsight
연결 설정:
Host: localhost
Port: 6380 ← 중요! (6379 아님)
Name: Docker Compose Redis
docker-compose ps
# 출력:
auction-app Up 2 min (unhealthy)
# 로그 확인
docker-compose logs app
# 헬스체크 로그
docker inspect auction-app | grep -A 20 Health
# 1. 재시작 시도
docker-compose restart app
# 2. 안 되면 재빌드
docker-compose build app
docker-compose up -d app
# 3. 여전히 안 되면 완전 재시작
docker-compose down
docker-compose up -d
Error: bind: address already in use
# macOS
lsof -i :8080
lsof -i :3307
lsof -i :6380
# Windows (PowerShell)
netstat -ano | findstr :8080
# 1. 충돌하는 프로세스 종료
kill -9 [PID]
# 2. 또는 docker-compose.yml에서 포트 변경
# ports:
# - "8081:8080" # 호스트 포트 변경
ERROR: failed to solve: process "/bin/sh -c ./gradlew bootJar" did not complete successfully
# 1. 캐시 삭제 후 재빌드
docker-compose build --no-cache app
# 2. 안 되면 전체 초기화
docker-compose down -v
docker system prune -a # 주의: 모든 이미지 삭제
docker-compose up --build -d
docker-compose ps
# 출력:
auction-app Restarting (137) # 137 = OOMKilled
# 로그에서 OOM 확인
docker-compose logs app | tail -50
# docker-compose.yml 수정
services:
app:
deploy:
resources:
limits:
memory: 1280M # 980M → 1280M 증가
Communications link failure
# MySQL 상태 확인
docker-compose ps mysql
# MySQL 로그 확인
docker-compose logs mysql
# MySQL이 healthy 상태가 될 때까지 대기
docker-compose up -d mysql
docker-compose logs -f mysql
# healthy 확인 후 app 재시작
docker-compose restart app
# 시작
docker-compose up -d # 백그라운드 시작
docker-compose up --build -d # 빌드 + 시작
# 중지
docker-compose stop # 중지 (데이터 유지)
docker-compose down # 삭제 (Volume 유지)
docker-compose down -v # 완전 삭제
# 컨테이너 상태
docker-compose ps # 상태 목록
docker stats # 리소스 사용량
curl http://localhost:8080/actuator/health # 헬스체크
# 로그
docker-compose logs -f # 전체 로그
docker-compose logs -f app # app만
docker-compose logs --tail=100 app # 최근 100줄
# 코드 수정 후
docker-compose build app # 재빌드
docker-compose up -d app # 재시작
# 또는 한 줄로
docker-compose up -d --build app
# MySQL
docker exec -it auction-mysql-compose mysql -u root -p
# Redis
docker exec -it auction-redis-compose redis-cli