kjp0411 님의 블로그

내일배움캠프 단기심화 Java - 본 캠프 Day 66 본문

TIL

내일배움캠프 단기심화 Java - 본 캠프 Day 66

kjp0411 2026. 5. 18. 22:23

TIL - 2026.05.18

오늘 한 일

오늘은 MSA 티켓팅 시스템의 서비스별 CI/CD 설정을 정리하고, 각 서비스가 GitHub Actions와 GHCR 기반 배포 흐름에 맞게 동작하도록 수정했다.

주요 작업은 다음과 같다.

  • club-service CI/CD 설정 확인
  • match-service CI/CD 설정 확인
  • payment-service CI/CD 설정 확인
  • queue-service CI/CD 설정 확인
  • reservation-service CI/CD 설정 확인
  • seat-service CI/CD 설정 확인
  • 테스트 실행 시 불필요한 인프라 의존성 비활성화
  • PR 머지 후 로컬 및 EC2 환경에서 최신 dev 브랜치 반영
  • docker-compose.app.yml 기준으로 서비스 재시작 및 정상 동작 확인

CI/CD를 도입하게 된 이유

이번 프로젝트는 MSA 구조로 구성되어 있기 때문에 서비스가 여러 개로 나뉘어 있다.

현재 프로젝트에는 user-service, club-service, match-service, seat-service, reservation-service, payment-service, queue-service 등 여러 애플리케이션 서비스가 존재하고, gateway-service, eureka-server, config-server 같은 인프라성 서비스도 함께 동작한다.

초기에는 각 서비스의 변경 사항이 생길 때마다 인프라 담당자가 직접 배포 서버에 접속해서 최신 코드를 반영하고, 필요한 컨테이너를 재시작하는 방식으로 배포를 진행했다.

서비스가 한두 개라면 이 방식도 크게 문제되지 않을 수 있다.

하지만 MSA 구조에서는 여러 팀원이 각자 다른 서비스에서 PR을 올리고, 해당 PR이 머지될 때마다 배포 서버에도 변경 사항을 반영해야 한다.

이 과정에서 인프라 담당자가 계속 실시간으로 머지 상황을 확인하고, 서버에 접속해 직접 pull, build, restart 작업을 수행해야 하는 점이 불편했다.

또한 수동 배포 방식은 다음과 같은 문제를 만들 수 있다.

  • 어떤 서비스가 최신 상태인지 확인하기 어렵다.
  • 특정 서비스만 재시작해야 하는 상황에서 실수할 가능성이 있다.
  • 배포 담당자에게 작업이 집중된다.
  • PR 머지 이후 배포 서버 반영까지 시간이 지연될 수 있다.
  • 반복적인 명령어 실행으로 인해 운영 피로도가 높아진다.

그래서 GitHub Actions와 GHCR을 활용해 서비스별 CI/CD 흐름을 정리하기 시작했다.

목표는 PR 머지 이후 각 서비스의 빌드, 테스트, 이미지 생성, 이미지 푸시 과정을 자동화하고, 배포 서버에서는 최신 이미지를 기반으로 서비스를 재실행할 수 있는 구조를 만드는 것이다.

이번 작업은 완전한 배포 자동화의 첫 단계라고 볼 수 있다.


문제 상황

서비스별 CI/CD 파일을 추가하거나 수정하는 과정에서 일부 서비스의 테스트가 실패했다.

특히 Spring Boot 테스트가 실행될 때 Config Server, Eureka, DB, Redis 등 외부 인프라 설정을 함께 읽으려고 하면서 contextLoads() 테스트가 실패하는 문제가 발생했다.

이 문제는 실제 서비스 로직의 오류라기보다는, CI 환경에서 테스트를 실행할 때 필요한 테스트 전용 설정이 충분히 분리되지 않았기 때문에 발생한 문제였다.


원인 분석

이번 문제의 핵심 원인은 테스트 환경과 실제 실행 환경이 명확하게 분리되지 않았다는 점이다.

로컬 환경에서는 Docker Compose로 Config Server, Eureka, DB, Redis 등이 함께 실행되기 때문에 문제가 드러나지 않을 수 있다.

하지만 GitHub Actions 같은 CI 환경에서는 해당 인프라들이 기본적으로 실행되어 있지 않다.

그런데 테스트 실행 시 실제 개발/운영 설정을 그대로 읽으려고 하면서 외부 인프라에 접근하게 되었고, 이로 인해 애플리케이션 컨텍스트 로딩이 실패했다.

즉, CI/CD 파이프라인 자체의 문제라기보다는 테스트 설정 분리 부족이 원인이었다.


해결 방법

서비스별 CI/CD 설정을 정리하면서 테스트 실행 시 불필요한 외부 의존성을 제거하거나 비활성화하는 방향으로 수정했다.

대표적으로 테스트 환경에서는 다음과 같은 설정이 필요했다.

spring:
  cloud:
    config:
      enabled: false

eureka:
  client:
    enabled: false
    register-with-eureka: false
    fetch-registry: false

이를 통해 테스트 환경에서는 Config Server와 Eureka Client에 의존하지 않도록 만들었다.

또한 각 서비스별 GitHub Actions workflow 파일을 정리하고, CI에서 ./gradlew clean test가 정상적으로 실행될 수 있도록 수정했다.


오늘의 기술 포인트

1. CI 환경과 로컬 환경은 다르다

로컬에서는 Docker Compose로 전체 인프라를 띄운 뒤 테스트하거나 API를 호출하기 때문에 정상 동작할 수 있다.

하지만 CI 환경에서는 GitHub Actions Runner 안에서 독립적으로 테스트가 실행된다.

따라서 로컬에서 성공한 테스트가 CI에서도 반드시 성공한다고 볼 수 없다.


2. 테스트 설정 분리는 필수다

Spring Boot 기반 MSA 프로젝트에서는 서비스가 많아질수록 Config Server, Eureka, DB, Redis, Kafka 등 외부 의존성이 증가한다.

이 상태에서 테스트 설정을 분리하지 않으면 간단한 테스트 하나도 외부 인프라 상태에 영향을 받게 된다.

따라서 테스트에서는 다음과 같은 원칙이 중요하다.

  • 외부 인프라 의존성을 최소화한다.
  • 테스트 전용 profile을 분리한다.
  • Config Server, Eureka 같은 운영 인프라는 테스트에서 비활성화한다.
  • 단순 contextLoads() 테스트라도 실제 설정을 모두 읽는다면 실패할 수 있음을 고려한다.

3. 서비스별 CI/CD 구조를 통일하는 것이 중요하다

MSA 프로젝트에서는 서비스가 여러 개이기 때문에 각 서비스의 CI/CD 방식이 다르면 유지보수가 어려워진다.

이번 작업을 통해 각 서비스의 workflow 구조를 비슷하게 맞추면서, 이후 다른 서비스에도 동일한 방식으로 적용할 수 있는 기준을 만들 수 있었다.

서비스별로 완전히 다른 방식으로 배포되는 것보다 공통된 패턴을 유지하는 것이 운영과 장애 대응 측면에서도 훨씬 유리하다.


4. 수동 배포는 서비스가 많아질수록 부담이 커진다

이번 작업을 하면서 MSA 환경에서 수동 배포가 얼마나 번거로워질 수 있는지 체감했다.

각 서비스가 개별 레포지토리와 개별 workflow를 가지게 되면, 특정 서비스의 PR이 머지될 때마다 배포 서버에 반영해야 할 대상도 늘어난다.

이때 인프라 담당자가 매번 서버에 접속해서 최신 코드를 가져오고, 이미지를 다시 빌드하고, 컨테이너를 재시작하는 방식은 장기적으로 유지하기 어렵다.

따라서 CI/CD는 단순히 편의를 위한 도구가 아니라, 반복적인 배포 작업을 줄이고 팀 전체의 개발 속도를 안정적으로 유지하기 위한 필수적인 구조라고 느꼈다.


오늘의 결과

오늘 작업을 통해 서비스별 CI/CD 설정을 대부분 정리했고, 수정된 내용도 PR을 통해 dev 브랜치에 반영했다.

또한 EC2 내부에서도 최신 dev 브랜치를 받아와서 서비스 재시작 흐름을 확인했고, 현재 기준으로 정상 동작하는 것을 확인했다.

이번 작업으로 서비스별 변경 사항을 GitHub Actions에서 빌드하고 테스트한 뒤, GHCR 이미지 기반으로 배포할 수 있는 기반이 마련되었다.

아직 완전히 자동화된 배포 구조는 아니지만, 기존처럼 모든 변경 사항을 인프라 담당자가 직접 실시간으로 서버에 반영해야 하는 방식에서 벗어나기 위한 첫 단계를 진행했다.


다음 할 일

  • 다른 팀원 서비스의 CI/CD 파일 반영 여부 확인
  • 전체 서비스 GHCR 이미지 기반 실행 흐름 점검
  • EC2 배포 환경에서 docker-compose.app.yml 기준 재시작 테스트
  • Gateway → 각 서비스 라우팅 정상 동작 확인
  • PR 머지 이후 배포 서버 반영 과정을 더 자동화할 수 있는 방법 검토
  • 배포 완료 후 전체 API 흐름 테스트

회고

오늘은 단순히 CI/CD 파일을 추가한 것이 아니라, MSA 프로젝트에서 배포 자동화를 왜 도입해야 하는지 직접 체감한 날이었다.

기존에는 서비스별 변경 사항이 생길 때마다 인프라 담당자가 배포 서버에 접속해 직접 반영해야 했다.

하지만 서비스 수가 늘어나고 팀원별 PR이 계속 머지되는 상황에서는 이런 방식이 점점 불편해지고, 실수 가능성도 높아질 수밖에 없다.

이번 작업을 통해 CI/CD는 단순히 배포를 빠르게 하기 위한 도구가 아니라, 반복적인 수동 작업을 줄이고 팀 전체가 안정적으로 개발을 이어가기 위한 기반이라는 것을 느꼈다.

앞으로는 GitHub Actions, GHCR, Docker Compose 기반 배포 흐름을 더 정리해서, 사람이 직접 서버에서 반복적으로 처리하던 작업을 점진적으로 자동화하는 방향으로 개선해가야겠다.