Skip to content

Feat/#1 CI/CD 구축 및 Netflix Eureka 서버 설정#2

Merged
1winhyun merged 16 commits intodevfrom
feat/#1
Sep 30, 2025
Merged

Feat/#1 CI/CD 구축 및 Netflix Eureka 서버 설정#2
1winhyun merged 16 commits intodevfrom
feat/#1

Conversation

@1winhyun
Copy link
Member

@1winhyun 1winhyun commented Sep 21, 2025

Related issue 🛠

작업 내용 💻

  • CICD를 구축했습니다.
  • Netflix Eureka Server를 구축하였습니다.

스크린샷 📷

local 서버

image

dev 서버

image

prod 서버

image + 추가적으로 prod 서버의 경우 8761번 포트의 경우 https 적용이 되어있지 않습니다. 왜냐하면 gateway를 포함한 서비스들이 eureka server에 등록이 되지만 모든 요청은 gateway-service에 해당하는 8000번 포트로 받아 각 서비스로 보내지기 때문입니다. 따라서 https 처리는 8000번 포트에 이루어졌습니다. 다음 사진은 해당 부분을 확인할 수 있는 nginx의 default.conf 코드입니다.
server {
    listen 80;
    server_name 43.200.160.0.nip.io;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
        allow all;
    }

    location /nginx/health {
        access_log off;
        return 200 'ok';
        add_header Content-Type text/plain;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
server {
    listen 443 ssl;
    http2 on;
    server_name 43.200.160.0.nip.io;

    ssl_certificate     /etc/letsencrypt/live/43.200.160.0.nip.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/43.200.160.0.nip.io/privkey.pem;

    # (옵션) mozilla 권장 설정을 쓰고 싶다면 아래 파일들이 있을 때 include
    # include /etc/letsencrypt/options-ssl-nginx.conf;
    # ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    client_max_body_size 10m;

    location / {
        proxy_pass         http://gateway-service-prod:8000;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    location /nginx/health {
        access_log off;
        return 200 'ok';
        add_header Content-Type text/plain;
    }
}

아키텍처

최종적으로 구축한 prod 서버의 아키텍처는 다음과 같습니다.
image
image

같이 얘기해보고 싶은 내용이 있다면 작성 📢

Summary by CodeRabbit

  • New Features
    • 서비스 디스커버리 서버(Eureka) 활성화
    • 환경별 구성 추가(local/dev/prod): 포트 8761, 클라이언트 등록/조회 비활성화, 서비스 목록 캐시 30초 갱신
  • Tests
    • 테스트 프로필 구성 추가(application-test): 서비스 디스커버리 비활성화 설정
    • 테스트 실행 시 테스트 프로필 활성화 설정 추가
  • Chores
    • CI 파이프라인 도입: 빌드·이미지 생성·푸시 자동화
    • CD 파이프라인 추가: dev/prod 원격 배포 자동화 및 이미지 정리
    • 컨테이너 실행용 이미지 구성 추가(Dockerfile)
  • Other
    • 기본 애플리케이션 이름 설정 제거 (application.properties)

@1winhyun 1winhyun self-assigned this Sep 21, 2025
@1winhyun 1winhyun added the chore chore label Sep 21, 2025
@1winhyun 1winhyun linked an issue Sep 21, 2025 that may be closed by this pull request
2 tasks
@1winhyun 1winhyun added the feature New feature or request label Sep 21, 2025
Copy link
Member

@huncozyboy huncozyboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 !

Comment on lines 13 to 15
server:
wait-time-in-ms-when-sync-empty: 0 # ?? ????? ??? ?? ??? ?? ?? ?? ?? ??
response-cache-update-interval-ms: 30000 # ??????? ??? ??? ?? ??? 30??? ??
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석으로 남겨주신 내용은 어떤 의미일까요 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 주석이 ?로 되어있었네요!! 주석 수정해놓았습니다.

우선 wait-time-in-ms-when-sync-empty: 0의 경우 서버가 동작할 때 레지스트리가 비어 있는 상태라면 얼마의 시간동안 응답을 지연할지 정하는 부분입니다. 즉, 0으로 설정할 경우 바로 서비스를 시작한다는 의미입니다.
다음으로 eureka.server.response-cache-update-interval-ms:30000의 경우 유레카 서버가 유지하는 읽기 전용 응답 캐시를 갱신하는 주기입니다. 즉, 등록과 해제가 일어나면 최대 30초 지연될 수 있다는 의미입니다.

@coderabbitai
Copy link

coderabbitai bot commented Sep 28, 2025

Walkthrough

CI 파이프라인과 dev/prod CD 워크플로우를 추가했으며, SSH 기반 원격 배포로 docker-compose 재배포를 수행하도록 구성했습니다. Spring Boot 애플리케이션에 Eureka 서버를 활성화하고, 환경별 YAML(profiles)과 테스트 프로필 설정, Dockerfile 및 Gradle 테스트 프로퍼티를 추가/수정했습니다. application.properties의 애플리케이션명은 제거되었습니다.

Changes

Cohort / File(s) Change Summary
GitHub Actions: CI/CD 파이프라인
.github/workflows/ci.yaml, .github/workflows/cd-dev.yaml, .github/workflows/cd-prod.yaml
CI 워크플로우(discovery-service CI pipeline) 추가(빌드·도커 빌드·푸시). CI 완료 후 트리거되는 dev/prod CD 워크플로우 추가. appleboy/ssh-action으로 원격 호스트에 SSH 접속해 docker-compose로 서비스 재배포(강제 제거, pull, up --no-deps) 및 이미지 정리 수행.
애플리케이션 진입점: Eureka 활성화
src/main/java/com/unionmate/discovery_service/DiscoveryServiceApplication.java
클래스에 @EnableEurekaServer 애노테이션 추가하여 Eureka 서버로 동작하도록 설정.
환경별 설정 파일 추가/수정
src/main/resources/application-dev.yml, src/main/resources/application-local.yml, src/main/resources/application-prod.yml, src/test/resources/application-test.yml
dev/local/prod/test용 프로파일 파일 추가: 서버 포트 8761, 환경별 애플리케이션명, Eureka 클라이언트 등록/조회 비활성화, 서버 초기 대기 0ms 및 응답 캐시 갱신 30s 등 설정.
Gradle: 테스트 프로파일 활성화
build.gradle
test 태스크에 시스템 프로퍼티 spring.profiles.active=test 추가.
Docker 런타임 이미지 추가
Dockerfile
OpenJDK 21 기반 Spring Boot 실행용 Dockerfile 추가(애플리케이션 JAR 복사 및 ENTRYPOINT 설정).
기본 프로퍼티 정리
src/main/resources/application.properties
기존 spring.application.name 설정 제거.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Dev as 개발자
    participant GH as GitHub Actions
    participant Reg as Docker Registry
    participant DevHost as DEV_HOST
    participant ProdHost as PROD_HOST

    Dev->>GH: push/PR to dev 또는 수동 실행
    GH->>GH: CI 실행 (checkout → Java/Gradle 빌드)
    GH->>Reg: Docker 이미지 빌드 및 푸시
    GH-->>GH: workflow_run 완료 -> CD 트리거

    rect rgba(200,240,255,0.25)
    note over GH,DevHost: CD (dev)
    GH->>DevHost: SSH 연결 (appleboy/ssh-action)
    DevHost->>DevHost: 컨테이너 강제 제거, docker-compose pull, up --no-deps, 이미지 prune
    end

    rect rgba(255,235,200,0.25)
    note over GH,ProdHost: CD (prod)
    GH->>ProdHost: SSH 연결 (appleboy/ssh-action, secrets 사용)
    ProdHost->>ProdHost: 컨테이너 강제 제거, docker-compose pull --always-pull, up --no-deps, 이미지 prune
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

당근을 품은 토끼가 뛰어와요 🐇
푸시 하나에 CI가 빵— 빌드가 완성되고
SSH로 살금, 컨테이너 다시 돋아요 🚀
유레카 소리로 서비스가 모이고
작은 당근으로 배포 축하할게요 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed 제목은 PR의 핵심인 CI/CD 구축과 Netflix Eureka 서버 설정을 명확하게 요약하고 있으며 불필요한 파일 목록, 이모지 또는 모호한 용어 없이 변경의 주된 의도를 잘 전달합니다.
Linked Issues Check ✅ Passed PR에서는 .github/workflows/ci.yaml, cd-dev.yaml, cd-prod.yaml를 추가하여 CI/CD 파이프라인 및 배포 워크플로우를 완성하고 DiscoveryServiceApplication에 @EnableEurekaServer 어노테이션과 application-*.yml 설정 파일을 추가하여 Eureka 서버 구성 요구사항을 모두 충족했습니다.
Out of Scope Changes Check ✅ Passed PR 내 모든 변경 사항은 CI/CD 구축과 Eureka 서버 설정이라는 이슈 #1의 목표 범위 내에 있으며 범위를 벗어나는 불필요한 코드나 설정 추가는 없습니다.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
build.gradle (1)

3-4: Spring Boot Gradle 플러그인 및 Spring Cloud 릴리스 트레인 버전 정렬
build.gradle 3–4행:

  • id 'org.springframework.boot' version '3.5.6' 로 업데이트
  • io.spring.dependency-management 플러그인으로 BOM에 spring-cloud-dependencies 2025.0.0 (Northfields) 적용
    spring-cloud-starter-netflix-eureka-server는 Spring Boot 3.5.x + Spring Cloud 2025.0.x와 호환됩니다.
🧹 Nitpick comments (5)
build.gradle (1)

25-30: Actuator 의존성 추가 권장(운영 관측/헬스체크 대비)

헬스 엔드포인트/프로브를 위해 actuator 추가를 권장합니다. 이후 Docker/K8s/Nginx 헬스체크와 연동이 수월해집니다.

다음 변경을 제안합니다:

 dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-web'
   implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
+  implementation 'org.springframework.boot:spring-boot-starter-actuator'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'
   testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
 }
Dockerfile (1)

1-5: 컨테이너 하드닝 및 종료 시그널 처리 개선

  • PID 1이 sh가 아닌 Java가 되도록 exec 사용 권장.
  • 기본 PROFILE(예: prod) 지정.
  • 루트가 아닌 전용 사용자로 실행.
  • 가능하면 JRE/slim 베이스로 경량화(선택).

제안 diff:

-FROM openjdk:21-jdk
+FROM openjdk:21-jdk

-COPY build/libs/*SNAPSHOT.jar app.jar
+# 전용 사용자 생성
+RUN useradd -r -s /bin/false appuser
+
+# JAR 복사(권한 소유자 지정)
+COPY --chown=appuser:appuser build/libs/*SNAPSHOT.jar /app.jar
+
+# 기본 프로파일 지정(배포 시 PROFILE로 override 가능)
+ENV PROFILE=prod

-ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -Dspring.profiles.active=${PROFILE} -jar /app.jar"]
+USER appuser
+ENTRYPOINT ["sh", "-c", "exec java ${JAVA_OPTS} -Dspring.profiles.active=${PROFILE} -jar /app.jar"]

비고:

  • 헬스체크를 사용하려면 actuator 추가 후 오케스트레이터에서 /actuator/health 사용을 권장합니다.
  • prod에서 Eureka 대시보드는 외부 노출을 차단하거나 내부망/접속 제어로 보호하세요(게이트웨이 외부 단일 진입점 유지).
src/test/resources/application-test.yml (1)

1-9: 테스트 포트 충돌 방지 설정 제안

통합테스트 시 고정 8080 충돌을 피하려면 랜덤 포트 바인딩을 권장합니다.

다음 변경을 제안합니다:

+server:
+  port: 0
 spring:
   application:
     name: discovery-service-test

 eureka:
   client:
     register-with-eureka: false
     fetch-registry: false
src/main/resources/application-local.yml (2)

8-12: Eureka 클라이언트 완전 비활성화 키 추가 권장

register-with-eureka=false, fetch-registry=false와 함께 enabled=false를 명시하면 관련 오토컨피그 로깅/네트워크 시도를 줄일 수 있습니다.

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

13-16: 로컬 편의 옵션(선택): 셀프 프리저베이션 해제 등

dev/local에서 등록 해제 지연을 최소화하려면 아래를 고려해 볼 수 있습니다(운영에는 비권장).

   server:
     wait-time-in-ms-when-sync-empty: 0  # 초기 레지스트리 정보가 비어 있어도 지연 없이 즉시 서버 시작
     response-cache-update-interval-ms: 30000  # 클라이언트에게 제공할 서비스 목록 캐시를 30초마다 갱신
+    enable-self-preservation: false       # LOCAL 전용
+    eviction-interval-timer-in-ms: 5000   # LOCAL 전용
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0128061 and 830c912.

📒 Files selected for processing (11)
  • .github/workflows/cd-dev.yaml (1 hunks)
  • .github/workflows/cd-prod.yaml (1 hunks)
  • .github/workflows/ci.yaml (1 hunks)
  • Dockerfile (1 hunks)
  • build.gradle (1 hunks)
  • src/main/java/com/unionmate/discovery_service/DiscoveryServiceApplication.java (1 hunks)
  • src/main/resources/application-dev.yml (1 hunks)
  • src/main/resources/application-local.yml (1 hunks)
  • src/main/resources/application-prod.yml (1 hunks)
  • src/main/resources/application.properties (0 hunks)
  • src/test/resources/application-test.yml (1 hunks)
💤 Files with no reviewable changes (1)
  • src/main/resources/application.properties
🔇 Additional comments (2)
build.gradle (1)

38-41: 테스트 프로파일 강제 활성화 👍

CI에서 테스트 격리를 보장하므로 적절합니다.

src/main/java/com/unionmate/discovery_service/DiscoveryServiceApplication.java (1)

7-9: Eureka 서버 활성화 적용 적절

@EnableEurekaServer 적용이 목적에 부합합니다. 추가 조정 없이도 기본 동작 OK입니다.

@UnionMate UnionMate deleted a comment from coderabbitai bot Sep 28, 2025
@UnionMate UnionMate deleted a comment from coderabbitai bot Sep 28, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
.github/workflows/cd-prod.yaml (1)

18-18: 배포 로그 식별을 위해 스텝 이름을 prod 환경에 맞춰주세요

프로덕션 워크플로우인데 스텝 이름이 dev로 남아 있으면 Actions 로그에서 환경을 오해할 수 있습니다.

적용 예시:

-      - name: Docker 이미지 dev 서버 배포
+      - name: Docker 이미지 prod 서버 배포
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 830c912 and 8b3bab0.

📒 Files selected for processing (2)
  • .github/workflows/cd-dev.yaml (1 hunks)
  • .github/workflows/cd-prod.yaml (1 hunks)

@UnionMate UnionMate deleted a comment from coderabbitai bot Sep 28, 2025
@UnionMate UnionMate deleted a comment from coderabbitai bot Sep 28, 2025
Copy link

@rootTiket rootTiket left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다~!!

@1winhyun 1winhyun merged commit 3a8e9b7 into dev Sep 30, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore chore feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] #1 CI/CD 구축 및 Netflix Eureka 서버 설정

3 participants