들어가기 앞서 . . .
전 포스팅에서는 개인 프로젝트의 CI/CD 구축 방법을 알아봤다.
하지만 개인 프로젝트의 CI/CD 구축 방법을 사용하면 다른 팀원과 사용할 경우 나의 github 게정의 노출이 존재하다는 단점이 있었고, EC2 서버가 빌드를 하도록 하기때문에, 서버에 부담이 간다는 점이 있다.
이번 포스팅에서는 소규모거나 그래도 좀 규모가 있는 프로젝트에서는 CI/CD를 어떻게 구축하는 지 알아보자.
전체적인 흐름
전체적인 흐름만 봐선 개인 프로젝트에 CI/CD를 구축하는 흐름과 크게 달라보이지않는다. 어느점에서 차이가 있는지 살펴보자.
- 개발자가 git push를 한다
- Github Actions가 서버를 빌드하고 테스트한다
- 빌드와 테스트를 성공하면 빌드 파일을 EC2에 전달한다
기존에 개인 프로젝트의 CI/CD 구축 방법은 Github Actions에서 빌드와 테스트를 진행하고 EC2가 빌드를 하게끔 설계했었다.
하지만 이렇게 진행하면 EC2가 서버를 빌드하게 되는데, 빌드를 하게 되면 생각보다 컴퓨터 자원(CPU, 메모리 등)을 많이 사용하게 되기 때문에 서버에 무리가 갈 수 있다.
이제 github Actions에서 프로젝트를 빌드하고, 빌드 파일을 EC2에 넘겨주는 방법으로 자동 배포를 구축해보자.
workflow 작성
name: Deploy TO EC2
on:
push:
branches:
- main
jobs:
Deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository에 올린 파일들을 불러오기
uses: actions/checkout@v4
- name: JDK 17버전 설치
uses: actions/setup-java@v4
with:
distribution: tenurin
java-version: 17
- name: application.yml 파일 만들기
run: echo "${{ secret.APPLICATION_PROPERTIES }}" > src/main/resources/application.yml
- name: 테스트 및 빌드하기
run: ./gradlew clean build
- name: 빌드 된 파일 이름 변경하기
run: mv ./build/libs/*SNAPSHOT.jar ./project.jar
- name: SCP로 EC2에 빌드된 파일을 전송하기
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secret.EC2_HOST }}
username: ${{ secret.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: project.jar
target: /home/ubuntu/seohaen-server/tobe
- name: SSH(원격 접속)로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.HOST }} # IP 주소를 말함
username: ${{ secrets.EC2_USERNAME }} # EC2를 연결할 때 사용자 이름
key: ${{ secrets.EC2_PRIVATE_KEY }} # EC2에 접근할 때 사용하는 키 페어
script_stop: true
script: |
rm -rf /home/ubuntu/seohaen-server/current
mkdir /home/ubuntu/seohaen-server/current
mv /home/ubuntu/seohaen-server/tobe/project.jar /home/ubuntu/seohaen-server/current/project.jar
cd /home/ubuntu/seohaen-server/current
sudo fuser -k -n tcp 8080 || true
nohup java -jar project.jar > ./output.log 2>&1 &
rm -rf /home/ubuntu/seohaen-server/tobe
코드해석
name: Deploy TO EC2
워크플로우의 이름을 지정한 것이다.
on: push -> branches: main
main 브랜치에 push가 발생했을 때 워크플로우가 실행되도록 설정한 것이다.
runs-on: ubuntu-latest
GitHub Actions에서 제공하는 최신 Ubuntu 환경에서 작업을 수행하도록 지정한 것이다.
- name: Github Repository에 올린 파일들을 불러오기
uses: actions/checkout@v4
레포지토리에 저장되어있는 코드를 불러오는 라이브러리이다.
Github Actions에서 Github에 푸쉬한 코드로 작업을 진행할 예정라는 것을 명시해주었다.
- name: JDK 17버전 설치
uses: actions/setup-java@v4
with:
# 어떤 브랜드를 사용할 것인가?
distribution: tenurin
# 어떤 버전을 설치할 것인가?
java-version: 17
JDK를 설치해주는 라이브러리다.
- name: application.yml 파일 만들기
run: echo "${{ secret.APPLICATION_PROPERTIES }}" > src/main/resources/application.yml
GitHub Secrets에 저장된 APPLICATION_PROPERTIES 값을 읽어와 application.yml 파일로 저장하는 단계이다.
- name: 테스트 및 빌드하기
run: ./gradlew clean build
Gradle 명령어를 사용하여 프로젝트를 클린 빌드하는 단계이다.
이 과정을 통해 build/libs 디렉토리에 .jar 파일이 생성된다.
- name: 빌드 된 파일 이름 변경하기
run: mv ./build/libs/*SNAPSHOT.jar ./project.jar
생성된 .jar 파일의 이름을 project.jar로 변경하는 단계이다.
파일 이름을 고정함으로써 이후 배포 과정에서 경로를 일관되게 관리할 수 있게 한다.
- name: SCP로 EC2에 빌드된 파일을 전송하기
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secret.EC2_HOST }}
username: ${{ secret.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
# 어떤 파일을 전송할 지에 대한 코드
source: project.jar
# 위의 파일을 Github에서 전송할건데 EC2의 어느 폴더에 전송할 것인가?
target: /home/ubuntu/seohaen-server/tobe
빌드된 project.jar 파일을 SCP(Secure Copy Protocol)를 사용해 EC2 서버로 전송하는 단계이다.
SCP는 SSH 기반으로 동작하므로, EC2 접근을 위한 정보(host, username, key)가 반드시 필요하다.
여기서 SCP란 내 컴퓨터나 깃허브 같은 서버에서 다른 컴퓨터(서버)로 파일을 보내는 방법 중 하나이다.
그냥 보내는 게 아니라, 보안을 위해 암호화를 하면서 안전하게 보내는 방식이다.
source는 로컬에서 전송할 파일을, target은 EC2에서 저장할 경로를 의미한다.
개인 프로젝트 CI/CD를 구축할 때 SSH 원격 접속을 통해 EC2에 접속하여 직접 빌드를 진행하도록 하였다.
하지만 이제 Github Actions에서 빌드된 파일을 넘겨줄 것 이기 때문에 yml파일을 생성하는 코드는 없어도 된다.
필요 없어진 코드에는 주석 처리를 해놓았다.
- name: SSH(원격 접속)로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
#env:
# APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
with:
host: ${{ secrets.HOST }} # IP 주소를 말함
username: ${{ secrets.EC2_USERNAME }} # EC2를 연결할 때 사용자 이름
key: ${{ secrets.EC2_PRIVATE_KEY }} # EC2에 접근할 때 사용하는 키 페어
script_stop: true
EC2 서버에 SSH(원격 접속)를 해서, 그 안에서 명령어를 실행하는 단계다.
appleboy/ssh-action이라는 GitHub Actions 플러그인을 사용해서, EC2에 접속하고 내부 명령어를 실행할 수 있게 한다.
이제 EC2 서버에서 빌드를 하는 것이 아니라 github actions에서 빌드를 해서 "빌드 파일만"넘겨줄 것이기 때문에, 환경변수로 application.yml을 넘겨주지않아도 되니 주석처리해주자.
script: |
rm -rf /home/ubuntu/seohaen-server/current
mkdir /home/ubuntu/seohaen-server/current
mv /home/ubuntu/seohaen-server/tobe/project.jar /home/ubuntu/seohaen-server/current/project.jar
cd /home/ubuntu/seohaen-server/current
sudo fuser -k -n tcp 8080 || true
nohup java -jar project.jar > ./output.log 2>&1 &
rm -rf /home/ubuntu/seohaen-server/tobe
script는 다시 작성해주어야한다.
- rm -rf /home/ubuntu/seohaen-server/current 기존에 currnet에 만들어진 서버 폴더와 파일을 삭제해준다
- mkdir /home/ubuntu/seohaen-server/current 폴더를 다시 만들어준다.
- Github Actions에서 빌드 후 저장한 project.jar 파일의 경로를 current로 옮겨준다. /home/ubuntu/seohaen-server/tobe/project.jar /home/ubuntu/seohaen-server/current/project.jar
- current 폴더로 이동한다
- 8080 포트가 실행중이라면 포트를 닫아준다.
- current 폴더로 옮겼던 project.jar 파일을 다시 실행시켜준다
- Github Actions에서 빌드해서 받았던 tobe 폴더는 삭제해준다.
성공적으로 자동 배포가 되는 것을 확인할 수 있었다!
마무리하며
이번 포스팅을 통해 CI/CD를 구축할 때 EC2 서버에 직접 접속해 빌드하는 방식 대신, GitHub Actions에서 빌드한 결과물만 EC2에 전달해 자동 배포하는 방식을 적용해보았다.
이런 구조는 EC2 서버에 가는 부하를 줄일 수 있다는 장점이 있으며, 협업 시에도 내 GitHub 계정 정보가 노출되지 않아 보안 측면에서도 더 안정적이다.
CI/CD는 단순히 자동화의 편리함을 넘어, 유지보수성과 확장성을 고려한 설계가 얼마나 중요한지를 깨닫게 해주는 도구라는 걸 다시 한 번 실감했다.
앞으로 더 규모가 있는 프로젝트나 협업 환경에서도, 이 구조를 바탕으로 안정적이고 효율적인 배포 환경을 구성해보고 싶다.
'Github Actions' 카테고리의 다른 글
[Github Actions] SpringBoot 개인 프로젝트 CI/CD 구축하기 (1) | 2025.06.18 |
---|---|
[Github Actions] CI/CD를 구축해 자동 배포를 해보자. (0) | 2025.06.18 |
[Github Actions] 배포 자동화, CI/CD란? (0) | 2025.06.18 |