


sudo yum install java-17-amazon-corretto -y
sudo alternatives --config java
java --version
왜 EC2에서 build를 하지 않고, GitHub Actions 같은 CI 서버에서 build를 하는걸까?
EC2는 배포용 서버이지 빌드용 서버가 아님: EC2는 실제로 서비스가 실행되는 운영 환경이며, 운영 서버에서는 빌드 작업처럼 무거운 연산을 피하는 것이 안정성에 유리함.
또한, 빌드 과정에서 리소스를 많이 쓰면 사용자 요청 처리에 지장이 갈 수도 있음
CI 서버에서 빌드하면 결과물이 검증된 상태라는 장점이 있다. 즉, 빌드가 성공한 경우에만 EC2로 전송하므로 안정성이 높다.
반대로, EC2에서 빌드 시 오류가 발생하면 서버가 중단 상태가 되어버릴 수 있음
버전 관리 + 오류 추적 가능: CI에서 빌드하고 배포하면: 누가 작성한 어떤 커밋 기준으로 빌드되었는지 등의 정보가 GitHub Actions 로그에 자동으로 남아서 이후 어떤 커밋의 코드가 오류의 원인인지도 명확히 확인할 수 있음
보안 측면에서도 EC2에는 최소한의 코드만 올리고 실행만 시키는 것이 소스코드 전체를 EC2에 복사하고 빌드하는 것보다 나음
Free Tier EC2는 용량이 작은 것에 반해, CI 서버(GitHub Actions)는 무료로 빠른 VM에서 빌드해줌. 즉, EC2가 무거운 빌드 안 해도 되니까 성능의 부담이 없음
Github Actions에 들어가서 미리 만들어진 workflow들을 가져올 수 있다. 우리는 우측 상단의 Java with Gradle을 사용해보자.
'minji03/library-app/**' 위치의 수정사항만 추적해야 하므로 아래와 같이 수정해주기on:
push:
branches: [ "main" ]
paths:
- 'minji03/library-app/**'
pull_request:
branches: [ "main" ]
- name: Build with Gradle Wrapper
run:
cd minji03/library-app
./gradlew build
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
paths:
- 'minji03/library-app/**'
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Build with Gradle Wrapper
working-directory: minji03/library-app
run: ./gradlew build
# NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html).
# If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version.
#
# - name: Setup Gradle
# uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
# with:
# gradle-version: '8.9'
#
# - name: Build with Gradle 8.9
# run: gradle build
# ~ 여기까지는 기존 템플릿 내용이고, 아래부터는 새로이 추가된 내용
- name: Ensure EC2 directory exists
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.EC2_HOST }}
username: ec2-user
key: ${{ secrets.EC2_KEY }}
script: mkdir -p /home/ec2-user/minji03/library-app/build/libs
- name: Copy JAR to EC2
uses: appleboy/scp-action@v0.1.3
with:
host: ${{ secrets.EC2_HOST }}
username: ec2-user
key: ${{ secrets.EC2_KEY }}
source: "minji03/library-app/build/libs/*.jar"
target: "/home/ec2-user/minji03/library-app/build/libs/"
- name: Deploy on EC2
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.EC2_HOST }}
username: ec2-user
key: ${{ secrets.EC2_KEY }}
script: |
echo ">>> Starting to deploy on EC2..."
cd /home/ec2-user/minji03/library-app
./deploy.sh
echo ">>> Deployment Successfully Completed"
# Additional changes in order to copy built JAR file to EC2 and deploy it on EC2 (여기까지가 추가된 내용)
dependency-submission:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies.
# See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
GitHub 레포지토리 → Settings → Secrets and variables → Actions로 접근해서 아래 두개의 변수를 Repository secrets로 등록하기.
EC2_HOST : EC2 퍼블릭 IP 주소EC2_KEY : 앞서 프로젝트 root에 복붙해두었던 .pem 파일을 열어서 내용을 통째로 복붙 (맨 앞/뒤 공백, 줄바꿈 포함!)
deploy.sh 파일 만들기minji03/library-app 위치로 이동한 후 vim deploy.sh 로 파일 생성, 아래 내용 붙여넣기#!/bin/bash
APP_NAME=minji03-library-app
JAR_PATH=$(ls /home/ec2-user/minji03/library-app/build/libs/*.jar | tail -n 1)
# 기존 프로세스 종료
PID=$(pgrep -f $JAR_PATH)
if [ -n "$PID" ]; then
echo ">> Kill process: $PID"
kill -15 $PID
sleep 5
fi
# 새로 실행
echo ">> Run $APP_NAME"
nohup java -jar $JAR_PATH > nohup.out 2>&1 &
chmod +x deploy.shgit add .
git commit -m "CI/CD test: 배포 트리거 테스트"
git push origin main
Actions 탭 → Workflow 실행 확인
ps -ef | grep java # 실행 중인 프로세스 확인
tail -f /home/ec2-user/minji03/library-app/nohup.out # 로그 실시간 확인