본문 바로가기
도커

SpringBoot 도커 배포, Dockerfile + build.sh 패턴 정리

by 이상한나라의개발자 2025. 8. 4.

Dockerfile

"환경"을 설계한다는 것의 의미

  • 모든 개발자와 운영자가 같은 환경에서 서비스가 실행되어야
    "내 로컬에선 되는데 서버에선 안 돼요" 문제가 사라진다.
  • 운영체제, JDK, 패키지, 파일 위치, 환경변수까지
    내 서비스에 필요한 모든 것을 한 줄 한 줄 ‘코드’로 문서화
    → Dockerfile은 이 과정을 **명령어(레시피)**로 적는 곳
  • 동일한 Dockerfile에서 빌드하면 "언제, 어디서, 누가 빌드해도" 완벽히 똑같은 이미지가 보장

실무에서 중요하게 여기는 포인트

  • FROM:
    절대로 아무 베이스 이미지나 쓰지 않는다.
    공식 이미지(예: eclipse-temurin, openjdk, gradle 등)만 채택
  • COPY:
    단순히 jar만 복사?
    → 실무에선 static 파일, config, script도 복사하게 되며
    → 이 단계에서 "파일명 오타, 위치 불일치" 실수 자주 발생
  • ENTRYPOINT vs CMD:
    ENTRYPOINT는 "무조건 실행되는 명령",
    CMD는 "기본 옵션"
    → 실무에서 ENTRYPOINT로 고정, CMD는 추가 옵션 줄 때만 씀
  • EXPOSE, ENV:
    실운영시 포트 노출, 환경변수 전달 미스 주의!
    (실제 운영 환경마다 값이 달라질 수 있기 때문)

build.sh가 실무에서 필수인 이유

"자동화"가 아니면, 언젠간 반드시 사람 손에서 실수난다

  • 이미지 빌드, 태깅, 푸시, 컨테이너 중지/삭제/재실행, 환경변수 주입 등
    한 번에 4~5단계 작업을 매번 터미널에서 직접?
    → 어제와 오늘, 내가, 동료가, QA가 할 때 항상 똑같이 잘 할 수 있을까?
    → 절대 불가능. 반드시 실수한다.
  • build.sh 한 방에 "반복/단순/재현" 문제 해결
    • 변수 하나로 포트, 버전, 환경값만 바꾸면
      → “빌드 → 푸시 → 배포”가 완벽히 동일하게 반복
    • 자동화 = 실수 방지 + 생산성 증가 + 기록(이력)

 

실무 자동화 스크립트 설계 시 주의점

  • set -e 꼭 넣자!
    어느 한 단계라도 실패하면 즉시 종료,
    → 실패 상태에서 컨테이너가 재시작되지 않도록!
  • 변수/인자 처리
    포트, 버전, 프로필, 환경변수 등
    → "반복"을 없애는 대신 "변수"로 관리.
    인자가 없으면 디폴트값으로, 있으면 동적으로 대응!
  • 중복 빌드/푸시 절대 금지!
    빌드/푸시는 한번만!
    (실수로 두 번 돌리는 경우 실시간 장애/트래픽 초과 가능)
  • docker rm -f로 기존 컨테이너 강제 삭제
    → 같은 이름의 컨테이너가 있으면 에러, 없으면 그냥 넘어감(실무에서 매우 유용!)

실무 배포 흐름의 본질 (도커 관점에서)

  • 내가 작성한 코드
    → (jar로 빌드)
    → (Dockerfile로 이미지 빌드)
    → (이미지에 태그 붙임)
    → (Docker Hub에 push, 운영/테스트/QA 서버에서 pull)
    → (기존 컨테이너 중지/삭제)
    → (새 이미지로 컨테이너 run, 환경에 따라 profile/port/secret 등 주입)
  • 이 모든 과정을 반복 가능하게 만드는 게 바로 build.sh!
    • build.sh 한 번만 실행하면
      → 코드, 환경, 이미지, 실행…
      모두 실수 없이 재현

예시

# Dockerfile

# 1. Java 17을 베이스 이미지로 사용
FROM eclipse-temurin:17-jdk-jammy

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. jar 파일 복사 (빌드 결과 jar)
COPY build/libs/hello-docker-study-0.0.1-SNAPSHOT.jar app.jar

# 4. 컨테이너 시작 시 실행될 명령어 지정
ENTRYPOINT ["java", "-jar", "app.jar"]

 

  • FROM으로 베이스 이미지(운영체제+JDK)를 지정
  • WORKDIR로 작업 경로 지정
  • jar 파일만 COPY
  • ENTRYPOINT로 앱 실행 명령 고정
#!/bin/bash

set -e  # 에러 발생 시 스크립트 즉시 종료

PROFILE=${1:-local}
VERSION=${2:-latest}

case "$PROFILE" in
  local|sandbox) PORT=8081 ;;
  prod1)         PORT=8082 ;;
  prod2)         PORT=8083 ;;
  *) echo "Unknown profile: $PROFILE"; exit 1 ;;
esac

DOCKER_USER="anthonyson904"
APP_NAME="hello-docker-spring"

# 1. jar 빌드
./gradlew build -x test

# 2. 도커 빌드 & 푸시
if [ "$VERSION" == "latest" ]; then
  docker build -t $DOCKER_USER/$APP_NAME:latest .
  docker push $DOCKER_USER/$APP_NAME:latest
else
  docker build -t $DOCKER_USER/$APP_NAME:$VERSION .
  docker tag $DOCKER_USER/$APP_NAME:$VERSION $DOCKER_USER/$APP_NAME:latest
  docker push $DOCKER_USER/$APP_NAME:$VERSION
  docker push $DOCKER_USER/$APP_NAME:latest
fi

# 3. 기존 컨테이너 중지 및 삭제
if [ "$(docker ps -q -f name=$APP_NAME)" ]; then
  docker rm -f $APP_NAME
fi

# 4. 새 컨테이너 실행 (:latest로)
docker run -d --name $APP_NAME -e SPRING_PROFILES_ACTIVE=$PROFILE -p $PORT:8080 $DOCKER_USER/$APP_NAME:latest

 

  • PROFILE/PORT/VERSION 등 인자로 관리(유연성↑)
  • 항상 최신 jar로 빌드
  • VERSION이 있으면 태깅/푸시/롤백까지 완벽 대응
  • 컨테이너 중지/삭제/재실행 자동
  • 환경변수로 Spring Profile 넘겨서 여러 환경에 대응

'도커' 카테고리의 다른 글

Dockerfile  (0) 2025.07.19
Docker Compose  (2) 2025.06.21