Skip to content

[Feat] AWS EC2 연결 추가 - #7

Merged
hyew0nn merged 3 commits into
devfrom
feat/ec2
Feb 12, 2026
Merged

[Feat] AWS EC2 연결 추가#7
hyew0nn merged 3 commits into
devfrom
feat/ec2

Conversation

@hyew0nn

@hyew0nn hyew0nn commented Feb 11, 2026

Copy link
Copy Markdown
Owner

📌 변경 내용

  • 무엇을 변경했는지 간단 요약

🛠 작업 상세

  • 구현한 핵심 로직
  • 수정/추가한 기능

✅ 체크 포인트

  • 정상 동작 확인
  • 기존 기능 영향 없음
  • 예외/경계값 처리

📎 참고 사항

  • 관련 이슈 / 고민한 점 / 추후 개선 사항

Summary by CodeRabbit

  • Chores

    • 배포 파이프라인을 EC2로 전환하여 SCP/SSH 기반 배포 및 Docker Compose 재시작으로 배포 흐름 개선
    • 빌드 환경을 Java Corretto 17로 업데이트하고 실행 가능한 JAR 아티팩트 생성 자동화
    • Docker 구성 업데이트(버전·서비스 이미지·포트 등) 및 실행 환경 포트 설정 정비
  • New Features

    • 로컬 전용 설정 파일 추가로 개발 환경 구성 간소화
    • 애플리케이션 서비스가 Docker Compose로 직접 구성/기동되도록 추가
  • Tests

    • 테스트 실행 시 별도 프로파일을 활성화하도록 테스트 구성 개선

@coderabbitai

coderabbitai Bot commented Feb 11, 2026

Copy link
Copy Markdown

Walkthrough

GitHub Actions CD 워크플로우를 EC2 SCP/SSH 배포로 교체하고 Java 17 + bootJar 빌드, Gradle 및 Docker Compose 관련 설정과 일부 애플리케이션 프로퍼티를 업데이트했습니다.

Changes

Cohort / File(s) Summary
CD 워크플로우
.github/workflows/cd_template.yaml
워크플로우 이름을 "Deploy EC2"로 변경. actions/checkout@v4로 업그레이드, actions/setup-java@v4로 Java 17(Corretto) 설정 추가. ./gradlew bootJar 실행 후 appleboy/scp-action으로 JAR을 EC2 /home/ec2-user/app에 전송하고 appleboy/ssh-action으로 docker-compose 기반 재시작 수행. 기존 Cloudtype 배포 블록 및 관련 토큰/프로젝트 설정 제거.
CI 워크플로우
.github/workflows/ci_template.yaml
push 이벤트 트리거 주석 처리(비활성화). actions/setup-java를 v4로 업그레이드하고 distribution을 corretto로 변경.
빌드 설정
build.gradle
bootJar task를 추가/설정하여 archiveFileName = "mse-project.jar"로 지정. 기본 jar task를 비활성화(enabled = false).
도커·런타임 설정
docker-compose.yaml, src/main/resources/application-docker.properties
docker-compose 버전 업그레이드(3 → 3.8). 새 app 서비스 추가(이미지 빌드, 포트/환경변수/depends_on 등). MySQL 이미지 및 Redis 버전 명시적 변경(mysql:8.0, redis:7). application-docker.properties의 MySQL 포트 23306 → 3306으로 수정.
애플리케이션 프로필 및 환경
src/main/resources/application.properties, src/main/resources/application-local.properties
application.properties에서 active 프로필 주석 처리(기존 local 주석 처리). application-local.properties 새로 추가: secret import 및 로컬 MySQL 데이터소스 설정 추가.
테스트 설정
src/test/java/com/mse_project/MseProjectApplicationTests.java
테스트 클래스에 @ActiveProfiles("test") 추가해 테스트 실행 시 test 프로파일 활성화.

Sequence Diagram(s)

sequenceDiagram
    participant Runner as GitHub Actions Runner
    participant Gradle as Gradle (./gradlew bootJar)
    participant SCP as appleboy/scp-action
    participant SSH as appleboy/ssh-action
    participant EC2 as EC2 Instance (Docker Compose)

    Runner->>Gradle: checkout + setup-java(17)\n./gradlew bootJar
    Gradle-->>Runner: build/libs/mse-project.jar (mse-project.jar)
    Runner->>SCP: scp mse-project.jar -> /home/ec2-user/app (SSH key)
    SCP-->>EC2: 업로드된 JAR 저장
    Runner->>SSH: ssh -> docker-compose -f /home/ec2-user/app/docker-compose.yaml up -d --build
    SSH-->>EC2: 컨테이너 중지/재빌드/시작 명령 실행
    EC2-->>Runner: 배포 완료 응답 / 로그
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 분

Possibly related PRs

Poem

🐰 깡충깡충 빌드가 뛰네,
jar 한 덩이 주머니 속,
SSH 길 따라 EC2로 훌쩍,
Docker가 춤추며 재시작,
당근 한입, 배포 축하 송! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 AWS EC2 연결 추가의 주요 변경 사항을 명확하게 요약하고 있으며, 제공된 파일 변경 사항들(CD 워크플로우 재구성, Docker Compose 설정, 배포 파이프라인 구축)과 일관성이 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ec2

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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)

45-47: ⚠️ Potential issue | 🔴 Critical

비공식 테스트 의존성을 제거하고 표준 Spring Boot 테스트 의존성으로 변경해야 합니다.

공식 Spring Boot 문서에 따르면 spring-boot-starter-data-jpa-test, spring-boot-starter-security-test, spring-boot-starter-webmvc-test는 공식적으로 권장되는 스타터가 아닙니다. 대신 다음 의존성을 사용하세요:

권장 변경 사항
-    testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa-test'
-    testImplementation 'org.springframework.boot:spring-boot-starter-security-test'
-    testImplementation 'org.springframework.boot:spring-boot-starter-webmvc-test'
+    testImplementation 'org.springframework.boot:spring-boot-starter-test'
+    testImplementation 'org.springframework.security:spring-security-test'

spring-boot-starter-test는 JUnit, AssertJ, Mockito, JSONassert, JsonPath 등 일반적인 테스트 라이브러리를 포함하고, spring-security-test는 Spring Security 테스트 지원(예: @WithMockUser)을 제공합니다.

🤖 Fix all issues with AI agents
In @.github/workflows/cd_template.yaml:
- Line 66: The deployment script's jar lookup uses the glob ${APP_NAME}-*.jar
which doesn't match the actual artifact name set in build.gradle
(archiveFileName = "mse-project.jar"), so update the lookup to use the exact
artifact name or a matching glob; specifically change the JAR discovery logic
(symbol: JAR_NAME) to look for ${APP_DIR}/${APP_NAME}.jar or adjust
build.gradle's archiveFileName to include the dash pattern so the existing
${APP_NAME}-*.jar glob will match.
- Around line 28-29: The workflow uses the GitHub Action reference
appleboy/scp-action@master which is unsafe; update that reference to a fixed
release tag (e.g., appleboy/scp-action@v1.0.0) so the step named "copy jar to
server" pins to a specific, audited version instead of `@master`.

In `@src/main/resources/application.properties`:
- Line 2: The hardcoded spring.profiles.active=docker in application.properties
reduces environment flexibility; remove that line from application.properties
and rely on runtime config (SPRING_PROFILES_ACTIVE env var or
-Dspring.profiles.active JVM arg) so different environments (local, CI, EC2) can
supply the appropriate profile; update deployment/CI scripts (startup command or
workflow) and any README/IDE run configurations to set the profile via
SPRING_PROFILES_ACTIVE or -Dspring.profiles.active instead of relying on the
application.properties value.
🧹 Nitpick comments (3)
.github/workflows/ci_template.yaml (1)

28-28: CI와 CD 간 setup-java 액션 버전이 불일치합니다.

CI에서는 actions/setup-java@v2를 사용하고 CD(cd_template.yaml Line 17)에서는 @v4를 사용합니다. 일관성과 최신 기능/보안 패치를 위해 @v4로 통일하는 것을 권장합니다.

제안
-        uses: actions/setup-java@v2
+        uses: actions/setup-java@v4
.github/workflows/cd_template.yaml (2)

72-75: 배포 후 애플리케이션 기동 확인(health check)이 없습니다.

nohup으로 백그라운드 실행 후 프로세스가 정상 기동되었는지 확인하지 않습니다. 앱이 즉시 크래시해도 워크플로우는 성공으로 표시됩니다.

간단한 health check 추가를 권장합니다:

제안: 기동 확인 추가
             nohup java -jar $JAR_NAME > $APP_DIR/app.log 2>&1 &
+            NEW_PID=$!
+            sleep 5
+            if ! ps -p $NEW_PID > /dev/null; then
+              echo "Error: Application failed to start. Check $APP_DIR/app.log"
+              tail -50 $APP_DIR/app.log
+              exit 1
+            fi
 
             echo "Deployment submitted successfully."

53-53: pgrep 패턴이 배포 프로세스 자체를 매칭할 수 있습니다.

pgrep -f "java.*$APP_NAME"은 SSH 세션에서 실행 중인 현재 스크립트의 환경 변수나 다른 Java 프로세스까지 매칭할 가능성이 있습니다. 보다 정확한 매칭을 위해 PID 파일 사용을 고려해 보세요.

Comment on lines +28 to +29
- name: copy jar to server
uses: appleboy/scp-action@master

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

appleboy/scp-action latest release GitHub

💡 Result:

The latest GitHub release of appleboy/scp-action is v1.0.0 (tag: v1.0.0), published Apr 27 (04:42) and marked Latest on the repo’s Releases page. [1]
GitHub Marketplace also shows the latest version as v1.0.0. [2]

Use in workflow: uses: appleboy/scp-action@v1 (or pin @v1.0.0). [2]

Sources: [1] [2]


appleboy/scp-action@master를 특정 버전으로 고정하세요.

@master를 사용하면 업스트림 변경이나 공급망 공격에 취약합니다. ssh-action은 특정 버전으로 고정되어 있으므로 scp-action도 동일하게 버전을 고정해야 합니다. 현재 최신 버전은 v1.0.0입니다.

제안
-        uses: appleboy/scp-action@master
+        uses: appleboy/scp-action@v1.0.0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: copy jar to server
uses: appleboy/scp-action@master
- name: copy jar to server
uses: appleboy/scp-action@v1.0.0
🤖 Prompt for AI Agents
In @.github/workflows/cd_template.yaml around lines 28 - 29, The workflow uses
the GitHub Action reference appleboy/scp-action@master which is unsafe; update
that reference to a fixed release tag (e.g., appleboy/scp-action@v1.0.0) so the
step named "copy jar to server" pins to a specific, audited version instead of
`@master`.

Comment thread .github/workflows/cd_template.yaml Outdated
Comment thread src/main/resources/application.properties Outdated
@hyew0nn
hyew0nn merged commit f9f7805 into dev Feb 12, 2026
1 of 2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.github/workflows/cd_template.yaml:
- Around line 38-48: The deployment step "Deploy with Docker Compose" currently
runs docker-compose down/up but only the JAR is copied to EC2, so transfer the
missing artifacts or change the deployment approach: either update the workflow
to SCP (or use appleboy/scp-action) to copy docker-compose.yaml, Dockerfile and
.env to the EC2 app directory before the SSH `script:` block; or replace the SSH
`script:` commands to run the JAR directly (e.g., `java -jar`) instead of
docker-compose; or modify CI to build and push a Docker image to a registry and
change the SSH `script:` to `docker-compose pull` and `docker-compose up -d` so
EC2 doesn’t need source files. Ensure the chosen fix updates the "script:" block
and the preceding copy step so docker-compose.yaml and Dockerfile are present on
EC2 when `docker-compose up --build` runs.
- Around line 35-36: The SCP action preserves source directories so using
source: "build/libs/*.jar" places files under /home/ec2-user/app/build/libs/...,
fix by adding the strip_components option for appleboy/scp-action (set
strip_components: 2) to flatten the path so the jar lands directly in the target
directory; update the workflow block containing the source/target keys to
include strip_components: 2.

In `@docker-compose.yaml`:
- Around line 17-27: The MySQL service (service name "mysql", container_name
"mse-mysql") lacks a persistent volume so its data is lost on recreate; add a
named volume (e.g., "mysql_data") and mount it to the container MySQL data dir
(/var/lib/mysql) by adding a volumes: entry under the mysql service (e.g.,
volumes: - mysql_data:/var/lib/mysql) and declare the named volume at the
top-level volumes: section (e.g., mysql_data: {}), ensuring Docker persists DB
files across docker-compose down/up cycles.
🧹 Nitpick comments (3)
src/main/resources/application-local.properties (1)

1-6: DB 자격 증명이 누락되어 있습니다.

spring.datasource.usernamespring.datasource.password가 이 파일에 없으므로, application-local-secret.properties에 반드시 포함되어야 합니다. 로컬 개발 시 해당 파일이 없으면 연결에 실패합니다. README 또는 주석으로 필요한 속성을 안내하면 좋겠습니다.

docker-compose.yaml (1)

4-15: depends_on만으로는 MySQL/Redis 준비 완료를 보장하지 않습니다.

depends_on은 컨테이너 시작 순서만 보장하며, MySQL이 실제로 연결을 수락할 준비가 되었는지는 확인하지 않습니다. Spring Boot 앱이 DB 연결 실패로 시작에 실패할 수 있습니다.

제안: healthcheck 조건 추가
   depends_on:
-      - mysql
-      - redis
+      mysql:
+        condition: service_healthy
+      redis:
+        condition: service_healthy

그리고 mysql, redis 서비스에 healthcheck를 추가하세요:

  mysql:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
.github/workflows/cd_template.yaml (1)

38-48: SSH 단계의 들여쓰기가 일관되지 않습니다.

with: 블록 내부의 속성들이 4칸 들여쓰기를 사용하고 있으나, 다른 단계들은 2칸을 사용합니다. YAML 파싱에는 문제가 없지만 일관성을 위해 통일하는 것이 좋습니다.

Comment on lines +35 to +36
source: "build/libs/*.jar"
target: "/home/ec2-user/app"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

SCP 전송 시 디렉토리 구조가 보존되어 파일 경로가 의도와 다릅니다.

appleboy/scp-action은 기본적으로 소스의 디렉토리 구조를 유지합니다. source: "build/libs/*.jar"로 전송하면 EC2에서 실제 경로가 /home/ec2-user/app/build/libs/mse-project.jar가 됩니다. strip_components 옵션을 사용하여 경로를 평탄화하세요.

제안
       - name: copy jar to server
-        uses: appleboy/scp-action@master
+        uses: appleboy/scp-action@v1.0.0
         with:
           host: ${{ secrets.SSH_HOST }}
           username: ec2-user
           key: ${{ secrets.SSH_KEY }}
           port: 22
           source: "build/libs/*.jar"
           target: "/home/ec2-user/app"
+          strip_components: 2
🤖 Prompt for AI Agents
In @.github/workflows/cd_template.yaml around lines 35 - 36, The SCP action
preserves source directories so using source: "build/libs/*.jar" places files
under /home/ec2-user/app/build/libs/..., fix by adding the strip_components
option for appleboy/scp-action (set strip_components: 2) to flatten the path so
the jar lands directly in the target directory; update the workflow block
containing the source/target keys to include strip_components: 2.

Comment on lines +38 to +48
- name: Deploy with Docker Compose
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.SSH_HOST }}
username: ec2-user
key: ${{ secrets.SSH_KEY }}
port: 22
script: |
cd /home/ec2-user/app
docker-compose down
docker-compose up -d --build No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

EC2에 docker-compose.yamlDockerfile이 전송되지 않아 배포가 실패합니다.

워크플로우는 JAR 파일만 EC2로 복사하지만, SSH 단계에서 docker-compose down / up --build를 실행합니다. docker-compose.yamlapp 서비스는 build: .을 사용하므로 EC2에 Dockerfiledocker-compose.yaml이 모두 필요합니다. 현재 이 파일들이 전송되지 않으므로 배포가 실패합니다.

해결 방안:

  1. 방법 A: docker-compose.yaml, Dockerfile, .env 등 필요한 파일도 함께 SCP로 전송
  2. 방법 B: EC2에서 docker-compose를 사용하지 않고 JAR를 직접 실행 (java -jar)
  3. 방법 C: Docker 이미지를 CI에서 빌드하여 레지스트리에 푸시하고, EC2에서 docker-compose pull로 배포
🤖 Prompt for AI Agents
In @.github/workflows/cd_template.yaml around lines 38 - 48, The deployment step
"Deploy with Docker Compose" currently runs docker-compose down/up but only the
JAR is copied to EC2, so transfer the missing artifacts or change the deployment
approach: either update the workflow to SCP (or use appleboy/scp-action) to copy
docker-compose.yaml, Dockerfile and .env to the EC2 app directory before the SSH
`script:` block; or replace the SSH `script:` commands to run the JAR directly
(e.g., `java -jar`) instead of docker-compose; or modify CI to build and push a
Docker image to a registry and change the SSH `script:` to `docker-compose pull`
and `docker-compose up -d` so EC2 doesn’t need source files. Ensure the chosen
fix updates the "script:" block and the preceding copy step so
docker-compose.yaml and Dockerfile are present on EC2 when `docker-compose up
--build` runs.

Comment thread docker-compose.yaml
Comment on lines 17 to +27
mysql:
image: mysql:latest
image: mysql:8.0
container_name: mse-mysql
ports:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

MySQL 데이터 영속성을 위한 볼륨이 없습니다.

docker-compose down 또는 컨테이너 재생성 시 MySQL 데이터가 모두 삭제됩니다. CD 워크플로우에서 매 배포마다 docker-compose downup --build를 실행하므로 배포할 때마다 DB가 초기화됩니다.

제안: 볼륨 추가
   mysql:
     image: mysql:8.0
     container_name: mse-mysql
     ports:
       - "23306:3306"
     environment:
       MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
       MYSQL_DATABASE: ${MYSQL_DATABASE}
       MYSQL_USER: ${MYSQL_USER}
       MYSQL_PASSWORD: ${MYSQL_PASSWORD}
+    volumes:
+      - mysql-data:/var/lib/mysql
+
+volumes:
+  mysql-data:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mysql:
image: mysql:latest
image: mysql:8.0
container_name: mse-mysql
ports:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
mysql:
image: mysql:8.0
container_name: mse-mysql
ports:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
🤖 Prompt for AI Agents
In `@docker-compose.yaml` around lines 17 - 27, The MySQL service (service name
"mysql", container_name "mse-mysql") lacks a persistent volume so its data is
lost on recreate; add a named volume (e.g., "mysql_data") and mount it to the
container MySQL data dir (/var/lib/mysql) by adding a volumes: entry under the
mysql service (e.g., volumes: - mysql_data:/var/lib/mysql) and declare the named
volume at the top-level volumes: section (e.g., mysql_data: {}), ensuring Docker
persists DB files across docker-compose down/up cycles.

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