Skip to content

ci 및 도커파일 main으로#6

Open
jaemin0413 wants to merge 12 commits intodevfrom
main
Open

ci 및 도커파일 main으로#6
jaemin0413 wants to merge 12 commits intodevfrom
main

Conversation

@jaemin0413
Copy link
Owner

@jaemin0413 jaemin0413 commented Nov 17, 2025

Summary by CodeRabbit

릴리스 노트

  • Chores
    • CI 워크플로우의 브랜치·캐시 설정 및 주석·들여쓰기 정리.
    • 테스트 실행 단계가 주석 처리되어 현재 테스트는 건너뜁니다.
    • 빌드·푸시 이미지 태그 형식 변경(loginwithjwt).
    • 새 배포 단계 추가: 원격 서버에 접속해 이미지 갱신, 컨테이너 교체 및 불필요한 이미지 정리 수행.
    • 애플리케이션 Docker 베이스 이미지 태그 업데이트.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Walkthrough

GitHub Actions 워크플로우를 정규화·수정하고(브랜치 표기·들여쓰기·테스트 단계 주석 처리), Docker 이미지 태그를 소문자로 변경하며, SSH 기반 원격 배포(이미지 풀 → 컨테이너 교체 → 이미지 프루닝) 단계를 추가했습니다. Dockerfile의 베이스 이미지 태그도 버전으로 변경되었습니다.

Changes

Cohort / File(s) 변경 요약
CI/CD 워크플로우
/.github/workflows/ci.yml
푸시 트리거 브랜치 표기 정규화(→ ["main"]), Gradle 캐시 블록 들여쓰기 조정, Run tests 단계 주석 처리(비활성화), Docker 이미지 태그 loginWithJWTloginwithjwt로 변경, 새로운 "Deploy to EX2" 섹션 추가(SSH로 원격서버 접속하여 이미지 pull → 기존 컨테이너 stop/remove → 새 컨테이너 run → 이미지 prune).
도커 이미지 설정
Dockerfile
베이스 이미지 태그를 bellsoft/liberica-openjdk-alpine:17-jre에서 bellsoft/liberica-openjdk-alpine:17로 변경(나머지 COPY/EXPOSE/ENTRYPOINT 동일).

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Repo as GitHub Repository
    participant Actions as GitHub Actions
    participant Build as Docker Buildx
    participant Registry as Docker Registry
    participant EX2 as Remote Server (SSH)

    Dev->>Repo: Push to main
    Repo->>Actions: Trigger CI workflow

    rect rgb(245,250,255)
    Actions->>Actions: Checkout, setup JDK 17, chmod +x ./gradlew
    Actions->>Actions: 빌드 실행 (테스트 단계는 주석 처리됨)
    Actions-->>Actions: build/libs/*.jar 생성
    end

    rect rgb(245,255,245)
    Actions->>Build: setup buildx & buildctl
    Actions->>Build: docker buildx build --tag ${DOCKER_USER}/loginwithjwt:latest --cache-from/--cache-to --push
    Build->>Registry: Push image
    Registry-->>Build: Push 완료
    end

    rect rgb(255,250,245)
    Actions->>EX2: SSH 접속 (secrets)
    Actions->>EX2: docker pull ${DOCKER_USER}/loginwithjwt:latest
    Actions->>EX2: docker stop/remove old container
    Actions->>EX2: docker run --name ... ${DOCKER_USER}/loginwithjwt:latest (env vars)
    Actions->>EX2: docker image prune -f
    EX2-->>Actions: 배포 결과 반환
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25분

  • 주의할 파일/영역:
    • /.github/workflows/ci.yml의 SSH 배포 단계: 시크릿(SSH 키) 사용 방식, 원격 명령의 안전성(권한/에러 처리/타임아웃) 검증.
    • 테스트 단계가 주석 처리된 의도와 복원 계획 확인.
    • 이미지 태그 변경(loginwithjwt)이 레지스트리와 배포 환경 전반에서 일관되는지 확인.
    • Dockerfile 베이스 이미지 변경에 따른 런타임 차이(패키지/라이브러리 호환성) 점검.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 한국어로 작성되어 있으며, 'ci 및 도커파일 main으로'는 CI 워크플로우와 Dockerfile의 주요 변경사항(main 브랜치 정규화, Docker 이미지 업데이트 등)을 부분적으로 반영합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch main

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: 8

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 323d9c7 and ded41a3.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml (1 hunks)
  • dockerfile (1 hunks)
🧰 Additional context used
🪛 Checkov (3.2.334)
dockerfile

[low] 1-15: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-15: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 YAMLlint (1.37.1)
.github/workflows/ci.yml

[warning] 5-5: truthy value should be one of [false, true]

(truthy)


[error] 7-7: too many spaces inside brackets

(brackets)


[error] 7-7: too many spaces inside brackets

(brackets)


[warning] 27-27: too few spaces before comment: expected 2

(comments)


[warning] 28-28: comment not indented like content

(comments-indentation)


[warning] 58-58: comment not indented like content

(comments-indentation)

🔇 Additional comments (1)
dockerfile (1)

1-15: HEALTHCHECK 명령어를 추가하여 컨테이너 헬스 체크를 구현하세요.

프로덕션급 컨테이너에서는 HEALTHCHECK 명령어가 필수적입니다. 현재 설정에서는 프로세스가 실행 중이더라도 애플리케이션이 실제로 응답 가능한 상태인지 Docker가 알 수 없습니다. 이것이 오케스트레이션 플랫폼(Docker Swarm, Kubernetes)이 컨테이너를 재시작하거나 재스케줄링하는 것을 방해합니다.

Spring Boot 애플리케이션의 경우, wget을 사용하여 /actuator/health 엔드포인트를 확인하는 것이 좋습니다 (curl은 권장하지 않음).
[raise_recommended_refactor]

헬스 체크를 추가하려면 다음을 참고하세요:

  WORKDIR /app
  
  COPY build/libs/*.jar app.jar
  
  EXPOSE 8080
  
+ HEALTHCHECK --interval=30s --timeout=3s --retries=1 \
+   CMD wget -qO- http://localhost:8080/actuator/health | grep UP || exit 1
+
  ENTRYPOINT ["java", "-jar", "app.jar"]

참고: 이 방법은 Spring Boot Actuator /actuator/health 엔드포인트가 활성화되어 있다고 가정합니다. 애플리케이션이 이 엔드포인트를 제공하지 않는 경우 Java 기반 헬스 체크를 작성할 수도 있습니다.

Comment on lines 27 to 28
cache: 'gradle' # gradle 의존성 캐싱, 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
# 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

주석의 들여쓰기 및 공백 형식을 수정하세요.

YAMLlint 경고가 있습니다. 주석 앞의 공백 수와 들여쓰기가 YAML 규칙을 따르지 않습니다.

다음과 같이 수정하세요:

-        cache: 'gradle' # gradle 의존성 캐싱, 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
-                        # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함
+        cache: 'gradle'  # gradle 의존성 캐싱
+        # 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
+        # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 27-27: too few spaces before comment: expected 2

(comments)


[warning] 28-28: comment not indented like content

(comments-indentation)

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 27-28, the inline comment's spacing and
indentation violate YAMLlint rules; fix by aligning the comment to the same
indentation level as the "cache" key, ensure there is exactly one space before
the '#' and exactly one space after it (or move the comment to its own line
above the key with the same indentation), and remove any extra leading or
trailing spaces so the file conforms to YAML linting expectations.

Comment on lines 30 to 34
# 3. 실행 권한 추가 및 빌드
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew bootJar --no-daemon
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

빌드 전에 테스트 단계를 추가하는 것을 권장합니다.

현재 워크플로우는 테스트 없이 바로 Docker 이미지를 빌드하고 푸시합니다. 프로덕션 안정성을 위해 테스트 단계를 추가하는 것이 좋습니다.

다음과 같은 테스트 단계를 추가하세요:

       - name: Build with Gradle
         run: ./gradlew bootJar --no-daemon
+
+      - name: Run tests
+        run: ./gradlew test --no-daemon

이렇게 하면 테스트가 실패할 경우 Docker 이미지 빌드가 진행되지 않습니다.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 30 to 34, the workflow grants execute
permission then builds with Gradle but skips running tests; insert a test step
between the chmod +x gradlew and the build step to run the test lifecycle (for
example run: ./gradlew test --no-daemon or ./gradlew check --no-daemon) so the
job fails fast on test failures and prevents Docker image build/push when tests
fail; keep the chmod step before the test step and ensure the subsequent build
step remains unchanged.

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew bootJar --no-daemon
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

--no-daemon 플래그의 이유를 명확히 하세요 (선택사항).

--no-daemon 플래그는 CI 환경에서 Gradle 데몬 프로세스를 방지하기 위해 사용됩니다. 이는 좋은 관행이지만, 워크플로우의 주석이 이를 설명하지 않습니다. 원하는 경우 다음과 같이 추가할 수 있습니다:

- name: Build with Gradle
  run: ./gradlew bootJar --no-daemon  # CI 환경에서 데몬 프로세스 비활성화
🤖 Prompt for AI Agents
.github/workflows/ci.yml around line 34: add a brief comment explaining why the
--no-daemon flag is used in CI; update the workflow line to include an inline
comment like “# Disable Gradle daemon in CI to avoid background processes and
permission/cleanup issues” or add a nearby YAML comment so future readers
understand the rationale.

Comment on lines 47 to 58
# 6. Docker 이미지 빌드 및 푸시 ( 캐시 옵션 추가)
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
# Docker 레이어 캐시 설정
cache-from: type=gha,mode=max
cache-to: type=gha,mode=max
# 이러면 변경된 부분만 새로 빌드함 No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Docker 이미지 태깅 전략을 개선하세요.

현재 워크플로우는 latest 태그만 사용합니다. 프로덕션 환경에서는 버전 관리가 필요합니다.

다음과 같이 개선하세요:

       - name: Build and push Docker image
         uses: docker/build-push-action@v5
         with:
           context: .
           file: ./Dockerfile
           push: true
-          tags: ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
+          tags: |
+            ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
+            ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:${{ github.sha }}
           cache-from: type=gha,mode=max
           cache-to: type=gha,mode=max

이렇게 하면 각 커밋의 SHA로 태그를 지정하여 버전 추적이 가능합니다.

🧰 Tools
🪛 YAMLlint (1.37.1)

[warning] 58-58: comment not indented like content

(comments-indentation)

🤖 Prompt for AI Agents
In .github/workflows/ci.yml around lines 47 to 58, the Docker push step
currently only tags images as "latest", which prevents traceable versioning;
update the step to add immutable tags such as the commit SHA and optionally the
branch/ref name (e.g., use GITHUB_SHA and/or github.ref_name) alongside "latest"
so each build is tagged with a unique identifier for rollbacks and auditing, and
ensure the tags input includes both the immutable tag(s) and the existing latest
tag and that push remains enabled.

dockerfile Outdated
Comment on lines 4 to 9
FROM bellsoft/liberica-openjdk-alpine:17-jre

WORKDIR /app

# ci.yml 의 5단계에서 이미 빌드한 jar 파일을 복사
COPY build/libs/*.jar app.jar
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

루트 사용자가 아닌 전용 사용자로 컨테이너를 실행하세요.

현재 Dockerfile은 기본 사용자(루트)로 컨테이너를 실행합니다. 이는 보안 위험입니다. 전용 사용자를 생성하고 권한을 제한하는 것이 권장됩니다.

다음과 같이 수정하세요:

  FROM bellsoft/liberica-openjdk-alpine:17-jre
  
  WORKDIR /app
  
+ RUN addgroup --system javauser && adduser -S -s /usr/sbin/nologin -G javauser javauser
+
  COPY build/libs/*.jar app.jar
+
+ RUN chown -R javauser:javauser /app
  
  EXPOSE 8080
  
+ USER javauser
+
  ENTRYPOINT ["java", "-jar", "app.jar"]

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In dockerfile around lines 4 to 9, the image currently runs as root; create a
dedicated non-root user and group, change ownership of /app to that user, and
switch to it before runtime. Add steps to create a system group and user (using
Alpine-friendly commands), chown /app (or the copied jar) to that user, and set
USER to the non-root account so the container runs with limited privileges.

WORKDIR /app

# ci.yml 의 5단계에서 이미 빌드한 jar 파일을 복사
COPY build/libs/*.jar app.jar
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

COPY 패턴의 견고성을 개선하세요.

COPY build/libs/*.jar app.jar 패턴은 build/libs/ 디렉토리에 정확히 하나의 JAR 파일이 있다고 가정합니다. 여러 JAR 파일이 있거나 파일이 없는 경우 예기치 않은 오류가 발생할 수 있습니다. 특히 빌드 프로세스에서 명시적으로 정확한 JAR 파일 이름을 지정하는 것이 좋습니다.

CI 워크플로우에서 Gradle bootJar 작업이 예측 가능한 이름의 JAR을 생성하는지 확인하고, 필요한 경우 파일 이름을 명시적으로 지정하세요.

🤖 Prompt for AI Agents
In dockerfile around line 9, the COPY instruction uses a fragile glob "COPY
build/libs/*.jar app.jar" which breaks if zero or multiple JARs exist; update
the Dockerfile to copy a single, explicit JAR name provided via a build-time ARG
(e.g. ARG JAR_FILE) or hardcode the deterministic filename produced by Gradle,
then use "COPY build/libs/${JAR_FILE} app.jar" (or the explicit filename) so the
Docker build fails clearly if the file is missing; also ensure the CI/Gradle
build sets the produced JAR filename predictably (via bootJar.archiveFileName or
archiveBaseName/version) and passes that name into docker build as --build-arg
JAR_FILE=... .

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: 1

♻️ Duplicate comments (5)
.github/workflows/ci.yml (5)

27-29: YAML 주석 들여쓰기 및 형식 수정

YAMLlint 규칙을 따르려면 cache 속성 다음의 주석들이 올바르게 들여써져야 합니다. 현재 들여쓰기가 일관성 없습니다.

다음과 같이 수정하세요:

         distribution: 'temurin'
         cache: 'gradle'
-          # gradle 의존성 캐싱, 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
-          # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함
+        # gradle 의존성 캐싱
+        # 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
+        # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함

52-62: Docker 이미지 태깅 전략 개선: 커밋 SHA 추가

현재 워크플로우는 latest 태그만 사용합니다. 프로덕션 환경에서는 각 빌드를 추적할 수 있도록 커밋 SHA 기반의 불변 태그(immutable tag)를 추가하는 것이 좋습니다.

다음과 같이 수정하세요:

       - name: Build and push Docker image
         uses: docker/build-push-action@v5
         with:
           context: .
           file: ./Dockerfile
           push: true
-          tags: ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
-          #  Docker 레이어 캐시 설정
+          tags: |
+            ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
+            ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:${{ github.sha }}
+          # Docker 레이어 캐시 설정
           cache-from: type=gha,mode=max
           cache-to: type=gha,mode=max
-          # 이러면 변경된 부분만 새로 빌드함
+        # 이러면 변경된 부분만 새로 빌드함

이렇게 하면 각 커밋에 대해 고유한 태그가 생성되어 롤백이나 감사 추적이 용이해집니다.


60-60: 주석 들여쓰기 수정 (line 60)

# Docker 레이어 캐시 설정 주석의 들여쓰기가 다른 키(cache-from, cache-to)와 맞지 않습니다.

다음과 같이 수정하세요:

           push: true
           tags: ${{ secrets.DOCKERHUB_USERNAME }}/loginWithJWT:latest
-          #  Docker 레이어 캐시 설정
+        # Docker 레이어 캐시 설정
           cache-from: type=gha,mode=max

63-63: 주석 들여쓰기 수정 (line 63)

마지막 주석이 cache-to 키와 같은 들여쓰기 수준에 있어야 합니다.

다음과 같이 수정하세요:

           cache-to: type=gha,mode=max
-          # 이러면 변경된 부분만 새로 빌드함
+        # 이러면 변경된 부분만 새로 빌드함

35-35: --no-daemon 플래그 설명 추가 (선택사항)

--no-daemon 플래그는 CI 환경에서 Gradle 데몬 프로세스를 비활성화하기 위한 것입니다. 이를 주석으로 명시하면 향후 유지보수가 용이합니다.

다음과 같이 추가할 수 있습니다:

       - name: Build with Gradle
-        run: ./gradlew bootJar --no-daemon
+        run: ./gradlew bootJar --no-daemon  # CI 환경에서 데몬 프로세스 비활성화
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89c7d69 and 41cbc31.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml (1 hunks)

Comment on lines 36 to 39
- name: Run tests
run: ./gradlew test --no-daemon
# 이러면 테스트 실패시 이미지 빌드 x

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

테스트 단계 주석 들여쓰기 수정

Line 38-39의 주석이 코드 블록과 같은 들여쓰기 수준에 있지 않습니다. 주석을 작업 이름 위나 run 다음에 인라인으로 배치하되, 들여쓰기를 일관되게 유지해야 합니다.

다음과 같이 수정하세요:

       - name: Run tests
         run: ./gradlew test --no-daemon
-        # 이러면 테스트 실패시 이미지 빌드 x
+        # 테스트 실패시 다음 단계로 진행하지 않음
🤖 Prompt for AI Agents
.github/workflows/ci.yml around lines 36 to 39: the comment after the run step
is misindented relative to the YAML job block; move the comment so its
indentation matches the surrounding keys (either place it on the same
indentation level as the job name or make it an inline comment after the `run`
line) and ensure consistent two-space indentation for that job block so the
comment aligns with other keys.

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

♻️ Duplicate comments (1)
dockerfile (1)

1-15: 루트 사용자 보안 이슈 및 COPY 패턴 견고성 문제가 여전히 미해결 상태입니다.

이전 리뷰에서 지적된 두 가지 주요 문제가 여전히 해결되지 않았습니다:

  1. 보안: 루트 사용자로 실행 (Major) - 컨테이너가 루트로 실행되고 있으며, 전용 비루트 사용자 생성이 필요합니다.
  2. 견고성: COPY 패턴 (Trivial) - COPY build/libs/*.jar app.jar 글로브 패턴은 정확히 하나의 JAR 파일만 있다고 가정합니다.

이전 리뷰의 제안을 참고하여 이 문제들을 해결하세요.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 41cbc31 and 47413e8.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml (3 hunks)
  • dockerfile (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build and Push to Docker Hub
🔇 Additional comments (2)
.github/workflows/ci.yml (1)

59-59: Docker 이미지 태그 이름 변경 검증

이미지 태그가 loginWithJWT에서 loginwithjwt로 변경되었습니다(소문자로). Docker Hub 이미지 이름은 일반적으로 소문자여야 하므로 이는 좋은 변경입니다. 빌드 및 배포 단계 모두에서 일관되게 사용되고 있습니다.

Docker Hub에 실제로 ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt로 푸시되도록 설정되어 있는지 확인하세요. 만약 이전에 loginWithJWT로 푸시되었다면, 새 이미지명으로 푸시하면서 이전 이미지는 정리해야 할 수 있습니다.

Also applies to: 80-80

dockerfile (1)

4-4: The base image uses :17, which is the BellSoft Liberica JDK image (includes development tools). For production Spring Boot deployments, using :17-jre (runtime-only) would be more appropriate and result in a smaller image. If this container is intended only for running the application without build tools, consider switching to bellsoft/liberica-openjdk-alpine:17-jre.

Likely an incorrect or invalid review comment.

Comment on lines +36 to +38
# - name: Run tests
# run: ./gradlew test --no-daemon
# 이러면 테스트 실패시 이미지 빌드 x, 나중에 하는걸로
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

테스트 단계가 주석 처리되어 있어 CI 신뢰성이 저하됩니다.

테스트 단계가 주석 처리되어 있습니다. 이는 검증되지 않은 코드가 프로덕션으로 배포될 위험성을 증가시킵니다. 테스트가 필요한 경우 이후에 추가하기로 계획 중이시면, GitHub Issue를 작성하거나 테스트 단계를 활성화하여 안정성을 보장하세요.

현재 주석을 제거하고 테스트를 활성화하거나, 명시적인 추적을 위해 TODO 이슈를 열 것을 권장합니다.

🤖 Prompt for AI Agents
.github/workflows/ci.yml lines 36-38: the test step is commented out which
reduces CI reliability; either re-enable the step by uncommenting the Gradle
test command (run: ./gradlew test --no-daemon) so tests run during CI, or if you
intentionally defer tests, create a tracked GitHub Issue and add a TODO comment
in the workflow pointing to that issue number; update the PR to include the
uncommented test step or the issue reference so CI behavior is explicit and
reproducible.

Comment on lines 78 to 90
script: |
# 도커 허브에서 최신 이미지 가져오기
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest

#기존 서버 중지 및 삭제
sudo docker stop login-server || true
sudo docker rm login-server || true

# 새 컨테이너 실행
sudo docker run -d -p 8080:8080 --name login-server ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest

# 미사용 이미지 정리
sudo docker image prune -f
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

배포 스크립트에 명시적 오류 처리 메커니즘이 없습니다.

SSH 스크립트에 set -e 또는 유사한 오류 처리 로직이 없습니다. 이로 인해 docker pull, docker run 등의 명령이 실패해도 워크플로우가 계속 진행될 수 있습니다.

또한 이 배포 단계에는 다음과 같은 위험성이 있습니다:

  1. 동시 배포 위험: 두 개의 워크플로우가 동시에 실행되면 예측 불가능한 상태가 발생할 수 있습니다.
  2. 롤백 메커니즘 부재: 배포 실패 시 이전 버전으로 복구할 방법이 없습니다.
  3. 헬스 체크 부재: 새 컨테이너가 정상 작동하는지 확인하지 않습니다.

배포 스크립트에 오류 처리와 검증 단계를 추가할 것을 권장합니다.

             script: |
+              set -e
               # 도커 허브에서 최신 이미지 가져오기
               sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest
               
               #기존 서버 중지 및 삭제
               sudo docker stop login-server || true
               sudo docker rm login-server || true
               
               # 새 컨테이너 실행
               sudo docker run -d -p 8080:8080 --name login-server ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest
+              
+              # 헬스 체크 (선택사항)
+              sleep 3
+              sudo docker ps | grep login-server || (echo "Container failed to start" && exit 1)
               
               # 미사용 이미지 정리
               sudo docker image prune -f
🤖 Prompt for AI Agents
.github/workflows/ci.yml around lines 78-90: the deploy script lacks fail-fast
error handling, concurrency protection, rollback, and health checks; update the
script to enable strict error handling (e.g., use set -euo pipefail or exit on
failures) so any failing docker command aborts the job, add a concurrency/lock
mechanism (e.g., use a lockfile or GitHub Actions concurrency/grouping) to
prevent simultaneous deployments, implement a simple rollback strategy (capture
the currently running container/image tag before stopping and, on failure,
redeploy that saved version), add a post-start health check with retries and
backoff (curl the service health endpoint and only consider deployment
successful if checks pass), and move image prune to run only after a successful
deployment; ensure all steps return non-zero on error so the workflow fails
correctly.

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: 1

♻️ Duplicate comments (2)
.github/workflows/ci.yml (2)

36-38: 테스트 단계가 주석 처리되어 있어 CI 신뢰성이 저하됩니다.

테스트 단계가 여전히 주석 처리된 상태입니다. 이전 리뷰에서 지적했던 문제가 해결되지 않았습니다. 검증되지 않은 코드가 프로덕션으로 배포될 위험성이 있습니다.

다음 중 하나를 선택하세요:

  1. 테스트를 즉시 활성화하려면 주석을 해제하세요
  2. 나중에 추가하기로 결정했다면, 이 PR 설명에 명시적으로 GitHub Issue 링크를 추가하고 워크플로우에 TODO 주석으로 참조하세요
-      # - name: Run tests
-        # run: ./gradlew test --no-daemon
-        # 이러면 테스트 실패시 이미지 빌드 x, 나중에 하는걸로
+      - name: Run tests
+        run: ./gradlew test --no-daemon

78-97: 배포 스크립트에 오류 처리 및 안정성 메커니즘이 부족합니다.

현재 배포 스크립트에는 다음과 같은 심각한 문제가 있습니다:

  1. 오류 처리 없음: docker pull, docker run 등 명령 실패 시 워크플로우가 계속 진행됨
  2. 동시 배포 위험: 두 개의 워크플로우가 동시 실행되면 예측 불가능한 상태 발생 가능
  3. 롤백 메커니즘 부재: 배포 실패 시 이전 버전으로 복구 불가능
  4. 헬스 체크 부재: 새 컨테이너가 정상 작동하는지 검증하지 않음

다음과 같이 개선하세요:

           script: |
+            set -euo pipefail
             # 도커 허브에서 최신 이미지 가져오기
             sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest
             
+            # 현재 실행 중인 컨테이너 백업 (롤백용)
+            PREVIOUS_IMAGE=$(sudo docker inspect --format='{{.Image}}' login-server 2>/dev/null || echo "none")
+            
             #기존 서버 중지 및 삭제
             sudo docker stop login-server || true
             sudo docker rm login-server || true
             
             # 새 컨테이너 실행
             sudo docker run -d -p 8080:8080 \
               -e LOCAL_DB_URL='${{ secrets.DB_URL }}' \
               -e LOCAL_DB_USERNAME='${{ secrets.DB_USERNAME }}' \
               -e LOCAL_DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \
               -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET }}' \
               -e JWT_ACCESS_TOKEN_VALIDITY='3600000' \
               -e JWT_REFRESH_TOKEN_VALIDITY='1209600000' \
               --name login-server ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest || {
+                echo "Failed to start container"
+                exit 1
+              }
             
+            # 헬스 체크 (최대 3회 시도)
+            for i in {1..3}; do
+              if sudo docker ps | grep -q login-server; then
+                echo "Container is running"
+                break
+              fi
+              if [ $i -eq 3 ]; then
+                echo "Container failed to start after 3 attempts"
+                exit 1
+              fi
+              sleep 1
+            done
+            
             # 미사용 이미지 정리
             sudo docker image prune -f
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 47413e8 and b4411b6.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml (3 hunks)
🔇 Additional comments (1)
.github/workflows/ci.yml (1)

59-59: No action needed. The Docker image tag loginwithjwt:latest is already consistent throughout the CI workflow (.github/workflows/ci.yml). Repository search found no references to a camelCase loginWithJWT docker tag in this project—all Docker tag references use lowercase loginwithjwt consistently in the build, pull, and deployment steps. There is no breaking change or migration concern.

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

♻️ Duplicate comments (4)
.github/workflows/ci.yml (4)

78-97: 배포 스크립트에 오류 처리 메커니즘을 추가하세요.

SSH 스크립트에 set -e가 없으므로, 명령 실패 시에도 이후 단계가 계속 실행될 수 있습니다. 이로 인해 불완전한 배포가 발생할 수 있습니다.

           script: |
+            set -e
             # 도커 허브에서 최신 이미지 가져오기
             sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest
             
             #기존 서버 중지 및 삭제
             sudo docker stop login-server || true
             sudo docker rm login-server || true
             
             # 새 컨테이너 실행
             sudo docker run -d -p 8080:8080 \
               -e LOCAL_DB_URL='${{ secrets.DB_URL }}' \
               -e LOCAL_DB_USERNAME='${{ secrets.DB_USERNAME }}' \
               -e LOCAL_DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \
               -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET }}' \
               -e JWT_ACCESS_TOKEN_VALIDITY='3600000' \
               -e JWT_REFRESH_TOKEN_VALIDITY='1209600000' \
               --name login-server ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest
             
             # 미사용 이미지 정리
             sudo docker image prune -f

36-39: 테스트 단계를 활성화하거나 추적 가능한 이슈로 등록하세요.

테스트 단계가 주석 처리되어 있습니다. 이는 검증되지 않은 코드가 프로덕션으로 배포될 위험성을 증가시키므로, 다음 중 하나를 수행하세요:

  1. 테스트 단계를 주석 해제하여 CI 중에 테스트가 실행되도록 함
  2. 나중에 추가할 계획이라면, GitHub Issue를 생성하고 워크플로우에 Issue 번호를 명시하여 추적 가능하게 함
       - name: Build with Gradle
         run: ./gradlew bootJar --no-daemon
-      # - name: Run tests
-        # run: ./gradlew test --no-daemon
-        # 이러면 테스트 실패시 이미지 빌드 x, 나중에 하는걸로
+      - name: Run tests
+        run: ./gradlew test --no-daemon

88-94: 환경 변수 전달 시 이중 따옴표를 사용하세요.

현재 코드는 GitHub Actions 시크릿을 단일 따옴표로 감싸고 있습니다. GitHub Actions 권장사항에 따르면, 시크릿을 docker run-e 플래그로 전달할 때는 이중 따옴표를 사용해야 합니다.

             # 새 컨테이너 실행
             sudo docker run -d -p 8080:8080 \
-              -e LOCAL_DB_URL='${{ secrets.DB_URL }}' \
-              -e LOCAL_DB_USERNAME='${{ secrets.DB_USERNAME }}' \
-              -e LOCAL_DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \
-              -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET }}' \
+              -e LOCAL_DB_URL="${{ secrets.DB_URL }}" \
+              -e LOCAL_DB_USERNAME="${{ secrets.DB_USERNAME }}" \
+              -e LOCAL_DB_PASSWORD="${{ secrets.DB_PASSWORD }}" \
+              -e JWT_SECRET_KEY="${{ secrets.JWT_SECRET }}" \
               -e JWT_ACCESS_TOKEN_VALIDITY='3600000' \
               -e JWT_REFRESH_TOKEN_VALIDITY='1209600000' \
               --name login-server ${{ secrets.DOCKERHUB_USERNAME }}/loginwithjwt:latest

27-29: 주석 들여쓰기를 수정하세요.

주석이 cache 키와 동일한 들여쓰기 수준에 있지 않습니다. 주석을 cache 위 라인에 배치하고 동일한 들여쓰기 수준으로 정렬하세요.

       - name: Set up JDK 17 with Gradle cache
         uses: actions/setup-java@v4
         with:
           java-version: '17'
           distribution: 'temurin'
+          # gradle 의존성 캐싱
           cache: 'gradle'
-            # gradle 의존성 캐싱, 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
-            # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함
+          # 이거 안 하면 한 번 받은 라이브러리는 캐시해두고 다음엔 바로 사용.
+          # 이거 안 하면 할 때마다 gradle 다 뒤져서 다운받아야 함
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b4411b6 and 9f12cbd.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Deploy to EX2
🔇 Additional comments (2)
.github/workflows/ci.yml (2)

7-7: 대괄호 내 공백 형식이 올바르게 수정되었습니다.

YAMLlint 오류가 해결되었습니다.


59-59: Docker 이미지 태그가 소문자로 올바르게 수정되었습니다.

Docker Hub의 이미지 명명 규칙을 준수합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant