Skip to content

Commit c40e113

Browse files
committed
[Feat] github-action을 사용하여 EC2 자동배포
1 parent 2c4368e commit c40e113

6 files changed

Lines changed: 85 additions & 63 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: Deploy HHPlus to EC2
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: read
10+
id-token: write # AWS OIDC 사용 시
11+
12+
jobs:
13+
build_and_push:
14+
name: 🚀 Build & Push to ECR
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
21+
- name: Set up JDK 17
22+
uses: actions/setup-java@v4
23+
with:
24+
distribution: temurin
25+
java-version: 17
26+
27+
- name: Generate Spring & Redisson config files
28+
run: |
29+
echo "${{ secrets.APPLICATION_PROPERTIES }}" > src/main/resources/application.yml
30+
echo "${{ secrets.REDISSON_DOCKER_YML }}" > src/main/resources/redisson-docker.yml
31+
echo "${{ secrets.REDISSON_LOCAL_YML }}" > src/main/resources/redisson-local.yml
32+
33+
- name: Build jar and Docker image (테스트 없이 진행)
34+
run: |
35+
chmod +x ./gradlew
36+
./gradlew clean build -x test
37+
docker build -t hhplus-app .
38+
39+
- name: Log in to Amazon ECR
40+
id: login-ecr
41+
uses: aws-actions/amazon-ecr-login@v2
42+
43+
- name: Tag Docker image for ECR
44+
run: |
45+
docker tag hhplus-app:latest ${{ steps.login-ecr.outputs.registry }}/hhplus-app:latest
46+
47+
- name: Push Docker image to ECR
48+
run: |
49+
docker push ${{ steps.login-ecr.outputs.registry }}/hhplus-app:latest
50+
51+
deploy:
52+
name: 🐳 Deploy via Docker Compose
53+
needs: build_and_push
54+
runs-on: ubuntu-latest
55+
56+
steps:
57+
- name: SSH to EC2 and update services
58+
uses: appleboy/ssh-action@v1.0.3
59+
with:
60+
host: ${{ secrets.EC2_HOST }}
61+
username: ${{ secrets.EC2_USERNAME }}
62+
key: ${{ secrets.EC2_PRIVATE_KEY }}
63+
script_stop: true
64+
script: |
65+
set -eux
66+
cd /home/ubuntu/hhplus-server-java # docker-compose.yml 위치
67+
export COMPOSE_HTTP_TIMEOUT=200 # 대형 이미지 pull 대비 타임아웃 증가
68+
docker-compose pull app # 앱 서비스 이미지만 새로 가져오기
69+
docker-compose up -d --no-deps app # 앱만 재시작
70+
# (옵션) 전체 스택 재시작: docker-compose up -d

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ out/
3737
.vscode/
3838

3939
data
40+
41+
application.yml
42+
redission-docker.yml
43+
redission-local.yml

Dockerfile

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
# ┌────────────────────────────────────────────────────────────────────────┐
2-
# │ Stage 1: Build Stage │
3-
# │ - Gradle Wrapper가 git 명령을 호출하므로, Alpine 컨테이너에 git을 설치 │
4-
# └────────────────────────────────────────────────────────────────────────┘
5-
FROM openjdk:17-jdk-alpine AS builder
6-
WORKDIR /app
1+
FROM eclipse-temurin:17-jdk-alpine
2+
COPY ./build/libs/*SNAPSHOT.jar project.jar
3+
ENTRYPOINT ["java", "-jar", "project.jar"]
74

8-
# Alpine 패키지 인덱스를 업데이트하고 Git을 설치
9-
RUN apk update && apk add --no-cache git
10-
11-
# 프로젝트 전체를 복사
12-
COPY . /app
13-
14-
# gradlew 실행 권한 부여 후, 테스트를 제외하고 빌드
15-
RUN chmod +x ./gradlew && ./gradlew clean build -x test
16-
17-
# ┌────────────────────────────────────────────────────────────────────────┐
18-
# │ Stage 2: Runtime Stage │
19-
# │ - JRE만 포함된 이미지로 빌드 결과(JAR)만 복사하여 실행 환경 구성 │
20-
# └────────────────────────────────────────────────────────────────────────┘
21-
FROM openjdk:17-alpine
22-
WORKDIR /app
23-
24-
# 빌드 스테이지에서 생성된 JAR 파일을 복사
25-
COPY --from=builder /app/build/libs/*.jar /app/app.jar
26-
27-
# 컨테이너가 리스닝할 포트(예: 8082)와 ENTRYPOINT 설정
28-
EXPOSE 8082
29-
ENTRYPOINT ["java", "-Dserver.port=8082", "-jar", "app.jar"]
5+
# 배포를 위한 docker file 생성

docker-compose.yml

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,6 @@ networks:
77

88
services:
99

10-
# ┌────────────────────────────────────────────────────────────────────────┐
11-
# │ 3) MySQL 서비스 정의 │
12-
# │ - 애플리케이션 데이터베이스로 사용되며, 포트 3306으로 외부와 통신합니다. │
13-
# │ - 로컬 디렉토리를 볼륨으로 마운트해 데이터 영속화를 보장합니다. │
14-
# └────────────────────────────────────────────────────────────────────────┘
15-
mysql:
16-
image: mysql:8.0 # MySQL 8.0 이미지를 사용 :contentReference[oaicite:20]{index=20}
17-
container_name: hhplus-mysql # 컨테이너 이름을 hhplus-mysql로 지정 :contentReference[oaicite:21]{index=21}
18-
ports:
19-
- "3306:3306" # 호스트 3306 → 컨테이너 3306 :contentReference[oaicite:22]{index=22}
20-
environment: # 환경 변수는 매핑(mapping) 형태로 작성 :contentReference[oaicite:23]{index=23}
21-
MYSQL_ROOT_PASSWORD: root # 루트 사용자 비밀번호 :contentReference[oaicite:24]{index=24}
22-
MYSQL_USER: application # 애플리케이션 전용 사용자 이름 :contentReference[oaicite:25]{index=25}
23-
MYSQL_PASSWORD: application # 애플리케이션 전용 비밀번호 :contentReference[oaicite:26]{index=26}
24-
MYSQL_DATABASE: hhplus
25-
restart: always
26-
# 초기 생성할 데이터베이스 이름 :contentReference[oaicite:27]{index=27}
27-
volumes:
28-
- ./data/mysql/:/var/lib/mysql # 호스트 ./data/mysql/ → 컨테이너 /var/lib/mysql (영속화) :contentReference[oaicite:28]{index=28}
29-
networks:
30-
- monitoring
31-
mem_limit: 1g # 이 컨테이너가 사용할 수 있는 최대 메모리 → 1GB
32-
cpus: 0.5 # 이 컨테이너가 최대 0.5 CPU 코어(50%) 사용 가능
33-
34-
3510
# ┌────────────────────────────────────────────────────────────────────────┐
3611
# │ 4) Kafka 서비스 정의 │
3712
# │ - 메시지 브로커로 사용되며, 포트 9094로 외부와 통신합니다. │
@@ -86,12 +61,11 @@ services:
8661
dockerfile: Dockerfile
8762
image: hhplus-app # 사용자 정의 이미지 이름을 hhplus-app으로 지정 :contentReference[oaicite:48]{index=48}
8863
depends_on:
89-
- mysql
9064
- kafka
9165
- redis
9266
# - influxdb # InfluxDB가 반드시 기동된 이후에 애플리케이션이 구동되도록 설정 :contentReference[oaicite:49]{index=49}
93-
environment: # Spring Boot 환경 변수는 매핑(mapping) 형태로 작성 :contentReference[oaicite:50]{index=50}
94-
SPRING_PROFILES_ACTIVE: docker # 활성화할 Spring 프로필을 local로 지정 :contentReference[oaicite:51]{index=51} # Kafka bootstrap 서버를 kafka 서비스로 지정 :contentReference[oaicite:57]{index=57}
67+
environment: # Spring Boot 환경 변수는 매핑(mapping) 형태로 작성
68+
SPRING_PROFILES_ACTIVE: docker # 활성화 할 프로파일을 docker로 지정함.
9569
restart: always
9670
ports:
9771
- "8082:8082" # 호스트 8082 → 컨테이너 8082 :contentReference[oaicite:62]{index=62}

src/main/java/kr/hhplus/be/server/presentation/concert/ConcertEventListener.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package kr.hhplus.be.server.presentation.concert;
22

33
import java.time.LocalDate;
4-
import java.time.ZoneId;
54

65
import org.springframework.scheduling.annotation.Async;
76
import org.springframework.stereotype.Component;
@@ -31,7 +30,6 @@ public class ConcertEventListener {
3130
@Async // 비동기 처리를 위한 어노테이션 추가
3231
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
3332
public void rankingUpdateListener(PaymentCompletedEvent event) {
34-
ZoneId zone = ZoneId.systemDefault();
3533
long availableSeats = concertRepository.getAvailableConcertSeat(event.scheduleId());
3634

3735
if (availableSeats != 0) {

src/main/resources/application.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ spring:
1616
generate-ddl: false
1717
show-sql: true
1818
hibernate:
19-
ddl-auto: none
19+
ddl-auto: update
2020
properties:
2121
hibernate.timezone.default_storage: NORMALIZE_UTC
2222
hibernate.jdbc.time_zone: UTC # 메시지 처리 확인 모드 - 수동 확인으로 처리 완료 후 커밋
@@ -99,10 +99,10 @@ spring:
9999
on-profile: docker
100100

101101
datasource:
102-
# Docker Compose 네트워크의 서비스 이름(mysql)로 접근
103-
url: jdbc:mysql://mysql:3306/hhplus?characterEncoding=UTF-8&serverTimezone=UTC
104-
username: application
105-
password: application
102+
# RDS 사용
103+
url: jdbc:mysql://hhplus-server-db.c2b2geu0c62c.us-east-1.rds.amazonaws.com:3306/hhplus?characterEncoding=UTF-8&serverTimezone=UTC
104+
username: admin
105+
password: hhplus-server-db
106106

107107
kafka:
108108
# Docker Compose 내에서 kafka:9092 로 접근

0 commit comments

Comments
 (0)