1️⃣ 들어가며
백엔드 프로젝트를 포트폴리오로 공유하면 항상 듣는 말이 있다.
“실행이 안 돼요… 😥”
백엔드 프로젝트는 실행하기 위해 생각보다 많은 준비가 필요하다.
예를 들어 내 프로젝트는 실행을 위해 다음이 필요했다.
- Java 설치
- MySQL 설치 및 실행
- Redis 설치 및 실행
- 환경변수 설정
- Gradle 빌드
- Spring Boot 실행
리뷰어 입장에서는
프로젝트 실행 자체가 큰 장벽이 된다.
그래서 이번 작업의 목표는 하나였다.
💡 docker-compose up 한 번으로 프로젝트 실행 가능하게 만들기
2️⃣ Docker란 무엇일까?

Docker를 한 줄로 설명하면 이거다.
“프로그램 실행에 필요한 모든 환경을 통째로 포장하는 기술”
보통 프로그램은 이렇게 실행된다.
내 코드 + OS + 라이브러리 + 런타임 + DB + 캐시
문제는 환경이 다르면 프로그램이 깨진다는 것이다.
예:
- 내 컴퓨터 → 잘됨
- 리뷰어 컴퓨터 → 안됨 😇
이걸 해결하기 위해 등장한 것이 Docker다.
컨테이너 개념
Docker는 프로그램을 컨테이너(Container) 라는 상자에 넣는다.
컨테이너 안에는 실행에 필요한 모든 것이 들어간다.
예:
- Java
- MySQL
- Redis
- 라이브러리
즉, 컨테이너만 실행하면 어디서든 동일하게 동작한다.
“내 컴퓨터에서는 되는데요?” 문제 해결 기술 = Docker
3️⃣ Docker Compose란 무엇일까?
Docker는 컨테이너 하나 실행할 때 사용한다.
하지만 백엔드는 보통 여러 서비스가 필요하다.
내 프로젝트도 3개가 필요했다.
- Spring Boot 서버
- MySQL DB
- Redis 캐시
이걸 각각 실행하려면 명령어를 여러 번 쳐야 한다.
그래서 등장한 것이 Docker Compose다.
Docker Compose는 여러 컨테이너를 한 번에 실행하는 도구다.
docker-compose up
여러 서비스를 동시에 실행할 수 있다.
4️⃣ 기존 프로젝트의 문제점
Docker 적용 전 실행 과정:
1️⃣ MySQL 설치
2️⃣ Redis 설치
3️⃣ 환경변수 수동 설정
4️⃣ Gradle 빌드
5️⃣ 서버 실행
즉, 실행 난이도 ★★★★★ 상태였다.
이걸 아래 상태로 바꾸는 것이 목표였다.
docker-compose up --build
5️⃣ 설계 전략
Docker를 적용할 때 가장 중요한 결정이 있었다.
기존 개발 환경을 절대 깨지 않기❗
이미 프로젝트에는 프로파일이 존재했다.
- local → 로컬 개발
- prod → 운영 환경
여기서 고민이 생긴다.
Docker 때문에 기존 환경이 깨지면 안 된다.
그래서 새로운 프로파일을 추가했다.
docker 프로파일 추가
최종 구조:
| 프로파일 | 목적 |
| local | 로컬 개발 |
| docker | Docker 실행 |
| prod | 운영 |
6️⃣ Dockerfile 만들기

Dockerfile은 이미지를 만드는 설계도다.
우리는 멀티 스테이지 빌드를 사용했다.
왜 멀티 스테이지 빌드인가?
일반 빌드 문제:
- Gradle 포함 → 이미지 용량 커짐 😨
멀티 스테이지 해결:
1단계 → Gradle로 빌드
2단계 → 실행만 하는 가벼운 이미지 생성
결과 → 이미지 경량화 🚀
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN chmod +x ./gradlew && ./gradlew bootJar -x test
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/build/libs/blog-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
이제 Java/Gradle 설치 없이 실행 가능하다.
7️⃣ Docker Compose 작성
여기서 가장 중요한 개념이 등장한다.
Docker 네트워크 DNS
컨테이너끼리는 서비스 이름으로 통신한다.
localhost ❌
mysql ⭕
redis ⭕
즉 Spring 설정도 변경해야 한다.
docker-compose.yml 핵심 구조
services:
mysql:
image: mysql:8.0
redis:
image: redis:7-alpine
app:
build: .
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
핵심 포인트:
DB와 Redis가 준비된 뒤 Spring이 실행된다.
8️⃣ Docker 전용 설정 만들기
Docker 내부에서는 localhost가 없다.
그래서 Docker 전용 설정 파일을 만들었다.
application-docker.yml
spring:
datasource:
url: jdbc:mysql://mysql:3306/blog
data:
redis:
host: redis
또 중요한 설정이 있다.
ddl-auto: update
리뷰어가 DB 스키마 생성할 필요 없게 만들었다.
환경변수 처리
Docker에서 가장 위험한 실수:
시크릿을 이미지에 넣는 것
그래서 .env.example 패턴을 사용한다.
.env → gitignore
.env.example → 커밋'프로젝트 > 공연 티켓팅 프로젝트' 카테고리의 다른 글
| 🎟️ 대기열 시스템에서 WebSocket 대신 Polling을 선택한 이유 (0) | 2026.06.01 |
|---|---|
| 🎟️ Redis로 좌석 차감을 옮겼는데도 Lock Wait이 사라지지 않았다. (0) | 2026.05.31 |
| 🎟️ MySQL 인덱스 실험: 예약 만료 배치 쿼리 성능 개선 (10만 건 실험) (1) | 2026.05.13 |
| 🎟️ 결제 API는 정말 중복 결제를 막을 수 있을까? (1) | 2026.04.27 |
| 🎟️ 예약 API 동시성 테스트 (다중 사용자 경쟁) 결과 보고 (1) | 2026.04.27 |