1. Dockerfile 작성

1-1. 멀티 스테이지 빌드 개념

멀티 스테이지 빌드는 Dockerfile을 **여러 개의 단계(stage)**로 나눠서 빌드하는 방식입니다. 대표적인 목적은 다음과 같습니다.

목표 설명 효과
빌드 툴 제거 Gradle, Maven, npm 등 빌드 전용 도구는 최종 이미지에서 제외 용량 절감, 보안성 강화
실행 환경 경량화 실행에 필요한 최소 JRE/라이브러리만 포함 컨테이너 기동 속도 향상
캐시 재사용 의존성 다운로드 단계와 소스 복사 단계를 분리 소스만 변경 시 빌드 시간 절감

구조 비교

(빌드 단계)          (실행 단계)
Gradle + JDK       JRE + app.jar
소스 코드            빌드 산출물만 복사
의존성 다운로드        실행 스크립트

1-2. Gradle 기반 Dockerfile 예시

# ====== build args는 반드시 FROM보다 위에 선언 ======
# 도커 빌드 시 사용할 빌드/런타임 이미지 이름을 변수로 지정
# ARG는 선언된 이후부터만 유효하므로 반드시 FROM보다 위에 있어야 함
ARG BUILDER_IMAGE=gradle:7.6.0-jdk17
ARG RUNTIME_IMAGE=amazoncorretto:17.0.7-alpine

# ============ (1) Builder ============
# 빌더 스테이지 시작: 지정한 Gradle + JDK 환경을 사용
FROM ${BUILDER_IMAGE} AS builder

# 루트 권한으로 변경 (권한 설정/폴더 생성 작업을 위해)
USER root
# 애플리케이션 작업 디렉토리 설정
WORKDIR /app
# Gradle 캐시 디렉토리 경로를 환경 변수로 설정 (빌드 속도 향상)
ENV GRADLE_USER_HOME=/home/gradle/.gradle
# Gradle 캐시 디렉토리와 앱 디렉토리 소유자를 gradle 유저로 변경
RUN mkdir -p $GRADLE_USER_HOME && chown -R gradle:gradle /home/gradle /app
# gradle 유저로 변경 (보안 및 권한 문제 방지)
USER gradle

# Gradle Wrapper 스크립트 복사 (빌드 실행에 필요)
COPY --chown=gradle:gradle gradlew ./
# gradle 폴더 복사 (wrapper 설정 및 실행 환경)
COPY --chown=gradle:gradle gradle ./gradle
# Gradle 설정 파일 복사 (빌드 스크립트)
COPY --chown=gradle:gradle build.gradle settings.gradle ./
# gradlew 실행 권한 부여
RUN chmod +x ./gradlew
# 의존성만 먼저 다운로드하여 캐시 활용 (코드 변경 없이 재사용 가능)
RUN ./gradlew --no-daemon --refresh-dependencies dependencies || true

# 실제 소스코드 복사 (이 시점 이후 변경 시 빌드 다시 수행됨)
COPY --chown=gradle:gradle src ./src
# 애플리케이션 빌드 (테스트 제외, 속도 향상)
RUN ./gradlew clean build --no-daemon --no-parallel -x test

# ============ (2) Runtime ============
# 런타임 스테이지: 빌드 결과 실행에 필요한 최소한의 경량 이미지 사용
FROM ${RUNTIME_IMAGE}
# 앱 실행 디렉토리 지정
WORKDIR /app

# 빌드 스테이지에서 생성한 JAR 파일만 복사
COPY --from=builder /app/build/libs/*.jar app.jar
# 애플리케이션이 사용하는 포트 노출
EXPOSE 8080
# Spring Boot 프로필을 운영(prod)으로 설정
ENV SPRING_PROFILES_ACTIVE=prod
# 컨테이너 시작 시 JAR 실행
ENTRYPOINT ["java","-jar","app.jar"]

1-3. 이미지 빌드 & 실행

# 1. 이미지 빌드
docker build -t my-spring-app:1.0 .

# 2. 컨테이너 실행
docker run -d -p 8080:8080 my-spring-app:1.0

1-4. 검증 명령어

# 컨테이너 확인
docker ps -a
# 로그 확인
docker logs -f <container_id>

2. 환경변수 설정 & 외부 설정 관리

2-1. 운영환경에서 DB 접속 정보 주입

2-1-1. application.yml 내부에서 사용중인 환경 변수

spring:
  datasource:
    url: ${SPRING_DATASOURCE_URL}
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}

2-1-2. 컨테이너 실행 시 외부에서 환경변수 주입