꿈소년의 개발 이야기

[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 08 도커를 이용한 애플리케이션 패키징 및 배포 본문

Do it 스터디!/스프링 부트 개발자 온보딩 가이드 스터디!

[스프링 부트 개발자 온보딩 가이드 스터디] Chapter 08 도커를 이용한 애플리케이션 패키징 및 배포

fogthegreat 2026. 4. 5. 21:28
반응형

DAY 10

🔖 오늘 읽은 범위 :

🌱공부 내용: Chapter 8 도커를 이용한 애플리케이션 패키징 및 배포
👢쪽수: p.347- p.384


  • 목표: 도커 기반의 Minilog-GraphQL 애플리케이션 패키징 및 배포
  • 기능 요구사항
    • 애플리케이션 빌드 시 Docker 이미지 자동 생성.
    • 명령어를 사용하여 AWS ECS에 애플리케이션 배포
  • 구현 요구사항
    • 데이터베이스: AWS RDS의 MySQL 사용.
    • Docker 패키징 시 AWS RDS 환경, 데이터베이스 연결 정보 및 계정 설정 사용.

Docker의 기본 개념과 설치

What is Docker?

What is Docker?

  • 도커(Docker): 컨테이너 기술을 기반으로 애플리케이션의 패키징, 배포, 실행을 관리할 수 있게 도와주는 오픈소스 플랫폼.
  • 컨테이너(Container): 애플리케이션을 포함하여, 애플리케이션 실행에 필요한 모든 라이브러리, 의존성, 환경 설정을 하나로 묶은 것.
    • 운영체제나 인프라 환경에 상관없이 일관된 방식으로 실행 가능.
  • 가상머신은?
    • 하이퍼바이저를 사용해서 호스트 운영체제 위에서 별도의 게스트 운영체제를 구동한다.
    • 높은 격리 수준을 제공함.
    • 각각 VM 마다 설치 및 관리해야 해서, 시스템 자원 소모가 심하다.
    • 실행 및 배포 시간이 상대적으로 오래 걸림.
  • 도커 컨테이너는?
    • 호스트 운영체제의 커널을 공유함.
    • 애플리케이션에 필요한 최소 운영 환경만 갖춘다.
    • 가볍고 빠르게 컨테이너 실행.
    • 리소스 사용량이 적음.
    • 간편한 배포와 관리.
    • 낮은 격리 수준 ⇒ 커널 격리성이 낮다.

Docker 구성 요소

  • Docker Image
    • Docker Container 실행을 위한 읽기 전용 템플릿.
    • 애플리케이션 코드, 의존성, 환경 설정등등 필요한 모든 정보를 포함한다.
    • Dockerfile 을 기반으로 생성된다.
  • Docker Container
    • Docker Image 기반으로 실제 애플리케이션이 동작하는 실행 환경.
  • Dockerfile
    • Docker Image 생성하기 위한 스크립트 파일.
    • 애플리케이션 소스 코드, 라이브러리, 의존성, 실행 명령 등을 정의한다.
  • Docker Daemon
    • 도커 명령을 처리하고, 컨테이너와 이미지들을 관리하는 프로세스.
    • 도커 데스크탑은 도커 데몬을 포함하고 있다.
    • AWS ECS 도 도커 데몬을 기반으로 컨테이너를 관리한다.
  • Docker Registry
    • 도커 이미지를 저장하고 공유할 수 있는 공간. 예를 들어 Docker Hub, AWS ECR 등등.
  • Docker Client
    • 도커 명령어를 실행하고, 도커 데몬과 통신하고, 컨테이너 및 이미지를 관리하는 사용자 인터페이스.

Dockerfile 작성 및 이미지 실행 테스트

application.properties 분리

Externalized Configuration :: Spring Boot

  • 스프링 부트 표준 프로파일 규칙
    • 형식: application-<프로파일이름>.properties
    • 다양한 환경에 맞춰 관리할 수 있도록 하는 기능.
    • 특정 환경에 특정 프로파일이 매칭 된다.
  • 프로필 이름에 따라 application-<profile name>.properties 파일이 자동으로 로드된다.
  • 프로파일 활성화 방법: ex) dev profile 활성화하는 경우.
    • 실행시 JVM 옵션으로 설정: -Dspring.profiles.active=dev
    • 환경변수로 설정: SPRING_PROFILES_ACTIVE=dev
    • 애플리케이션 내에서 설정: SpringApplication.setAdditionalProfiles(”dev”)

build.gradle 수정

bootRun {
    String activeProfile = System.properties['spring.profiles.active']
    systemProperty "spring.profiles.active", activeProfile
}

Dockerfile 작성

# Docker 이미지 - 베이스 이미지 설정
FROM openjdk:21-jdk-slim

# /tmp 디렉터리를 볼륨 설정
VOLUME /tmp

# jar 파일 경로를 지정하는 인자(기본값: build/libs/*.jar)
ARG_JAR_FILE=build/libs/*.jar

# 지정된 jar 파일을 이미지 내부의 app.jar 로 복사
COPY ${JAR_FILE} app.jar

# prod 프로파일을 사용해 production 설정을 적용. <-- 로컬 환경에서 이 부분을 오버라이드 해야 함.
ENV_SPRING_PROFILES_ACTIVE=prod

# 컨테이너 시작 시 실행할 명령어 정의.
ENTRYPOINT ["java","-jar","/app.jar"]
// 도커 빌드 명령으로 minilog-graphql 이미지 생성.
> docker build -t minilog-graphql:latest .

// 도커 이미지 생성 확인.
> docker images | grep minilog-graphql

개발 로컬 환경에서 컨테이너 실행 및 테스트

  • 개발 환경에서 도커 이미지 실행하기

      > docker run -e SPRING_PROFILES_ACTIVE=dev --network="host" minilog-graphql
    • docker run
      • 도커 이미지 기반으로 새로운 컨테이너 생성하여 실행한다.
    • -e SPRING_PROFILES_ACTIVE=dev
      • 환경 변수를 통해서 스프링 부트 프로파일을 dev로 지정한다.
      • application-dev.properties 를 읽어서 설정한다.
    • --network="host"
      • 도커 컨테이너가 호스트 머신의 네트워크를 직접 공유하게 한다.
      • 컨테이너는 기본적으로 호스트와 분리된 네트워크를 사용한다.
      • 이 옵션은 localhost 를 컨테이너가 아닌 호스트 머신의 localhost 를 의미하게 한다.
      • 이 옵션을 사용하게 되면, 별도의 포트 매핑(-p) 없이도 동일한 포트를 공유하여 사용할 수 있다.
    • minilog-graphql
      • 실행할 도커 이미지의 이름.

AWS 에 배포하기

AWS 엑세스 키 및 비밀 엑세스 키 생성

  • AWS 계정으로 가입 한 후 액세스 키 생성한다.
  • 액세스 키 생성 후 두 가지 정보를 안전하게 복사해 보관한다.
    • Access Key ID
    • Secret Access Key

WSL2 - AWS CLI 설치

> curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
> unzip awscliv2.zip
> sudo ./aws/install
> aws --version
> aws configure

Amazon RDS, ECR, ECS 이해하기

  • Amazon RDS: Relational Database Service
    • 클라우드 상에서 쉽게 관리할 수 있는 데이터베이스 서비스.
    • 여러가지 DBMS를 지원한다.
    • 데이터베이스 설치, 운영, 백업, 복구 등등 작업들을 자동화 한다.
  • Amazon ECR: Elastic Container Registry
    • 컨테이너 이미지에 대해 안전하게 저장, 관리 및 배포할 수 있는 관리형 컨테이너 이미지 레지스트리 서비스.
    • 여기에 앱 도커 이미지를 업로드 한다.
  • Amazon ECS: Elastic Container Service
    • 도커 컨테이너를 손쉽게 관리하고 배포할 수 있도록 지원하는 완전 관리형 컨테이너 오케스트레이션 서비스.
    • 자동으로 컨테이너 배포, 확장, 관리를 처리한다. ← 운영 복잡성 감소.
    • 애플리케이션이 실행할 환경.

등록 및 배포하기

Amazon RDS MySQL 인스턴스 설정

  • AWS 관리 콘솔을 통해서 RDS에서 MySQL 인스턴스를 설정한다.

기본 보안 그룹 인바운드 속성 편집

  • RDS 를 통해 인스턴스를 생성하면, 별도 설정 없이 기본 VPC 보안 그룹을 사용하게 된다.
  • 기본 VPC 보안 그룹(방화벽)의 설정을 통해, 인스턴스에 앱과 외부 데이터베이스 관리 도구에서 접근이 가능하도록 변경한다.

application-prod.properties 수정

  • 예시

      spring.datasource.url=jdbc:mysql://<RDS-엔드포인트>:3306/minilog_db
      spring.datasource.username=<RDS에서 설정한 사용자 이름>
      spring.datasource.password=<RDS에서 설정한 비밀번호>
      spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

Amazon ECR 에 Docker 이미지 등록

  • Amazon ECR 에 이미지를 업로드해야 한다.
  • 컨테이너는 “완전 관리형 도커 컨테이너 레지스터”를 선택한다.
  • 리포지토리 생성 후 이미지 푸시 명령어를 확인한다.
  • 확인한 명령어들을 실행하여 이미지를 업로드 한다.

Amazon ECS 클러스터에 앱 배포하기

  • 1단계 ECS 클러스터 생성하기
    • “Elastic Container Service” 선택(컨테이너를 매우 안전하고, 안정적이고, 확장 가능한 방식으로 실행)
    • 클러스터 생성.
    • AWS Fargate(서버리스) 선택
    • 생성.
  • 2단계 Task Definition(작업 정의) 생성하기
    • Amazon ECS 콘솔에서 태스트 정의 선택하기.
    • 새로 항목 생성.
    • AWS Fargate 체크.
    • 운영체제는 Linux/X86_64
    • .5CPU / 1GB 메모리
    • 컨테이너 포트 8080 / 프로토콜 TCP / 포트 이름: container-port-protocol / 앱 프로토콜 HTTP
    • 환경 변수
      • 키: SPRING_PROFILES_ACTIVE
      • 값 유형: 값
      • 값: prod
    • 생성
  • 3단계 ECS 서비스 생성하기
    • 실질적인 배포 단계
    • “Elastic Container Service” 선택
    • 생성한 클러스터 선택
    • 서비스 생성.
    • 컴퓨팅 옵션 “시작 유형” 선택.
    • 시작 유형 “FARGATE” 선택.
    • 플랫폼 버전 “LATEST” 선택.
    • 배포 구성에서 애플리케이션 유형 “서비스” 선택
    • 태스크 정의 패밀리 → <앱이름>-task
    • 태스크 정의 계정 → 1
    • 서비스 이름 ⇒ <앱이름>-service
    • 서비스 유형 → “복제본” 선택.
    • 원하는 태스크 → 1
    • 네트워킹 VPC → 기본값
    • 보안그룹 → 새 보안그룹
    • 보안 그룹 이름 → tcp-inbound-8080
    • 보안 그룹 설명 ⇒ Allow 8080 Port
    • 보안 그룹 인바운드 규칙
      • 유형: 사용자 지정
      • 프로토콜: TCP
      • 포트 범위: 8080
      • 소스: 사용자 지정
      • 값: 0.0.0.0/0
    • 생성
  • 4단계 배포 결과 확인하기
    • Status: 활성
    • Deployment and tasks: 태스크 실행 중
    • Last deployment: 완료됨
    • 서비스 목록 → 해당 서비스 항목 선택 → 상세 페이지
    • 정보 중 태스크 탭 → 현재 실행 중인 태스크 선택
    • 태스크 상세 페이지 → 퍼블릭 IP 확인.
  • 퍼블릭 IP 는 테스트 페이지에서 사용한다.

Swagger-UI/GraphiQL를 이용한 API 테스트

  • http://<퍼블릭 IP>:8080/swagger-ui/index.html
  • http://<퍼블릭 IP>:8080/graphiql
  • AWS 설정이 많아서 이런 인프라는 따로 공부가 더 필요하다.

🤟소감 3줄 요약

  • 인프라는 쉽지 않다.
  • 매뉴얼, 가이드 문서는… 너무 많아..
  • 으아…
반응형