들어가기 앞서 . . .
저번 포스팅에서 간단하게 CI/CD의 기본 이론과 어떤식으로 동작하는지에 대해 알 수 있었다.
이번 포스팅에서는 이를 바탕으로, SpringBoot 개인 프로젝트에 직접 CI/CD를 구축해보는 과정을 정리하고자 한다.
GitHub Actions와 EC2를 활용해 자동으로 배포가 이루어지도록 설정하고,
실제로 코드만 push했을 때 서버에 자동으로 반영되는 흐름을 구현해보며 실전에서 CI/CD가 어떻게 적용되는지 체감해보자.
CI/CD 전체적인 흐름
개인 프로젝트에서의 CI/CD 구축 흐름은 아래와 같다.

위와같은 흐름은 장단점이 명확하게 드러난다.
장점
- git push를 활용해서 변경된 부분의 프로젝트 코드에 대해서만 업데이트 하기 때문에 CI/CD 속도가 빠르다
- 대부분의 CI/CD는 전체 프로젝트를 통째로 갈아끼우는 방식을 사용한다.
- CI/CD 툴로 Github Actions만 사용하기 때문에 인프라 구조가 비교적 간단하다.
단점
- 빌드 작업을 EC2에서 직접 진행하기 때문에 서버의 성능에 영향을 미치거나 성능에 영향을 미칠 수 있다.
- 프로젝트를 빌드하는 과정은 생각보다 컴퓨터의 자원 (CPU, 메모리 등)을 많이 잡아먹는다. EC2 서버가 돌아가고 있는데 거기서 빌드까지 돌리게 되면 서버의 자원이 모자라서 서버가 멈춰버리거나, 성능에 영향을 미칠 수 있다.
- Github 계정 정보가 EC2에 저장되기 때문에 개인 프로젝트 혹은 신뢰가 있는 사람들과 진행하는 토이 프로젝트에서만 사용하도록 하자.
개인 Springboot 프로젝트에 CI/CD를 구축해보자
SpringBoot 프로젝트 생성하기
우선 자동 배포화를 진행하기 위해서 Springboot 프로젝트를 생성해보자.
dependency에 devTools와 Web 추가해주자.

Controller 추가
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AppController {
@GetMapping("/")
public String home() {
return "최종 CI/CD 배포 TEST ";
}
}
workflows 추가 및 해석
name: Deploy TO EC2
on:
push:
branches:
- main
jobs:
Deploy:
runs-on: ubuntu-latest
steps:
- name: SSH(원격)로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
envs: APPLICATION_PROPERTIES
script_stop: true
script: |
cd /home/ubuntu/personal-cicd-server
rm -rf src/main/resources/application.yml
git pull origin main
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.yml
./gradlew clean build
sudo fuser -k -n tcp 8080 || true
nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
코드를 하나하나 해석해보자.
- name: SSH(원격)로 EC2에 접속하기
uses: appleboy/ssh-action@v1.0.3
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }}
SSH로 EC2에접속하는 작업이다.
서버를 배포하기 위해서는 EC2에 접속해야하는데, 이런 EC2등 원격 컴퓨터에 접속하기 위해 사용하는 프로토콜이 SSH이다.
Github Actions도 하나의 컴퓨터고, EC2도 하나의 컴퓨터이므로 SSH를 통해서 원격 접속을 진행해주자.
일일이 다 쳐도 되지만 불편하기때문에 github actions의 라이브러리를 사용해주었다.
uses는 내가 어떤 라이브러리를 쓸 건지 기재하는 곳이다.
env은 환경 변수를 선언하는 부분인데, APPLICATION_PROPERTIES를 써서 application.yml의 내용을 환경변수에 추가할 예정이다.
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
envs: APPLICATION_PROPERTIES
script_stop: true
with는 어떤 원격 컴퓨터와 연결할 것이냐를 뜻한다.
host에는 EC2의 IP 주소,
username은 EC2를 연결할 때 사용자 이름
key는 EC2 인스턴스에 접근할 때 사용하는 키 페어
envs는 어떤 변수를 사용할 지 지정해주는 부분인데, 우리는 위에서 만들어준 환경변수인 APPLICATION_PEROPERTIES라는 변수를 사용한다.
script: |
cd /home/ubuntu/personal-cicd-server
rm -rf src/main/resources/application.yml
git pull origin main
echo "$APPLICATION_PROPERTIES" > src/main/resources/application.yml
./gradlew clean build
sudo fuser -k -n tcp 8080 || true
nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &
script 부분에는 EC2에 접속해서 실행한 명령어들을 차례대로 작성해주자.
script 아래줄부터의 차례대로 설명해보자면
1. 프로젝트의 해당 경로로 이동
2. github에서 프로젝트 pull
3. gradlew 재 빌드
4. 포트번호 8080서버를 끄거나 서버가 이미 꺼져있어도 true
5. SNAPSHOT.jar로 끝나는 파일을 실행. 로그는 output이라는 파일에 남김
여기서 필자는 nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 & 부분을 EC2에서 직접 빌드할 때 처럼 nohup라는 명령어를 빼고 java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &만 입력했다가 무수한 에러를 맛봤다... 잘 입력해주자.
CI/CD 테스트를 해보자.
github repository를 만들었다.
이제 서버를 배포하기 위해 EC2를 만들어보자.

CI/CD를 구축하는 포스팅이기때문에 EC2 인스턴스를 생성하는 방법은 다루지않겠다!
EC2 인스턴스를 생성하는 방법을 모르겠다면 아래의 포스팅을 참고해서 만들자. 탄력적 IP 전까지만 하면 된다
(아래 보안그룹 부분을 추가해야하니 기억해놨다가 보안그룹 생성하는 부분에서 같이 생성해주자 !)
https://dev-haen.tistory.com/62
[AWS]AWS EC2 설정하기
들어가기 앞서 . . .클라우드 환경에서 내 서비스를 배포하고 싶을 때 가장 많이 쓰는게 AWS EC2 인스턴스이다.저번 포스팅에서 EC2 기초 지식을 공부했으니 이번엔 EC2를 처음 써보는 사람도 쉽게
dev-haen.tistory.com
EC2 보안그룹을 추가해주자.
Springboot의 기본 포트번호는 8080으로, 8080이라는 포트번호로 요청을 보내면 EC2에 접근할 수 있도록 8080포트번호를 보안그룹에 추가해주어야한다.


EC2 연결하기
EC2 서버에 자바를 깔아야하므로 아래의 명령어를 EC2에 차례대로 입력 후, 버전을 확인해보자.
성공적으로 자바 17버전이 깔린 것을 확인할 수 있다.
$ sudo apt update
$ sudo apt install openjdk-17-jdk -y
$ java -version

EC2서버에 git repository를 클론해주자.

git clone https://github.com/....
클론하기 위해서는 git id와 토큰값을 입력해주어야한다.
토큰 값을 한 번 입력하면 앞으로 물어보지 않도록 설정하기
git ID와 토큰값을 입력하여 프로젝트를 성공적으로 clone 해왔다.
이후 코드 업데이트가 진행되면 항상 git Id와 토큰 값을 입력해야하는데 토큰값은 생성할 때 알려주고 이후 알 수 있는 방법이 없기때문에 잃어버리면 또 새로운 토큰을 생성하고 입력해주어야한다.
토큰 값을 한 번 입력하면 앞으로 물어보지 않도록 설정해보자.
EC2 서버에서 해당 프로젝트의 폴더로 이동해 아래의 명령어를 실행시켜준다.
$ git config --global credential.helper store
한 번 로그인을 하면 계정과 토큰 값 (비밀번호 값)을 저장해놓겠다는 명령어다.

git config —global credential.helper store 명령어를 실행시킨 뒤, git pull origin main 명령어를 입력하면 처음엔 계정과 토큰 값을 입력받고있다.
계정과 토큰 값을 입력 후 다시 git pull origin main을 연달아서 입력하게 되면 계정과 토큰 값을 다시 입력하지않아도 바로 pull 되는 것을 확인할 수 있다.
이 과정은 매번 계정과 토큰 값을 입력하기 귀찮아서도 있지만, 배포 자동화인 CI/CD 구축을 위해 필요한 과정이니 잘 알아두도록 하자.
아래의 명령어를 입력해보자.
$ cd ~
$ ls -a #숨겨진 파일을 모두 보여주는 명령어

.git-credentials라는 파일이 생성되었다.
아래의 명령어로 파일을 열어보자.
cat .git-credentials

잘라서 안보이지만 나의 깃 계정과 토큰값이 노출되는 것을 확인할 수 있었다.
이런식으로 아까 말했던 단점인 깃 계정이 노출된다는 것이 문제점이다.
EC2를 혼자 사용하면 모르겠지만 다른 사람들과 협업하게되면 이런식으로 깃 계정이 모두 노출되어 보안이 취약하다.
클론을 해왔다면 해당 프로젝트로 이동하여 빌드해주자.
$ cd personal-cicd-server
$ ./gradlew clean build
빌드가 끝나면 프로젝트 폴더/build/libs 로 이동하여 -SNAPSHOT.jar로 끝나는 파일로 서버를 실행시키자
$ sudo java -jar personal-cicd-server-0.0.1-SNAPSHOT.jar

이렇게 배포까지 해보았다.
CI/CD가 탄생하게 된 배경은 매번 코드로 수정하고 업데이트 하기 번거롭기 때문이다.
지금까지 한 배포 작업을 코드가 수정되면 매번 해줘야 하는 것이다.
커맨드 + C를 눌러 EC2에서 실행중이던 스프링 서버를 꺼주고, github Actions를 이용해보자.
배포가 자동으로 되는지 확인해보자.
그 전에 EC2 IP, 키 페어등을 Secret 변수에 추가해주자.
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
EC2_HOST
- EC2 서버의 IP를 작성해주면 된다.
EC2_USERNAME

EC2_PRIVATE_KEY

다 등록해주었다.

컨트롤러를 변경해보았다.
변경 전

변경 후

CI/CD 자동배포 테스트해보기
main 브랜치에 push를 하고 CI/CD가 성공되는지 확인해보자.


아까의 페이지를 새로고침해보자.

EC2에 직접 git을 pull하고, build를 새로 하고, 빌드 파일을 새로 실행해주지도않았다.
코드만 push했을 뿐인데 직접 우리가 EC2 서버에서 pull하고 build하고 새로 빌드파일을 실행한 것 처럼 자동으로 빌드와 배포가 진행됐다.
마무리하며
직접 EC2에 접속하지 않아도, 코드만 push하면 자동으로 빌드되고 배포되는 과정을 경험하면서 CI/CD의 핵심 가치를 실감할 수 있었다!
GitHub Actions와 SSH를 연동해, 실제 운영 서버에 원격으로 접속하여 빌드와 배포까지 자동으로 처리하는 과정은 수동 배포의 번거로움을 획기적으로 줄여줬고, 반복 가능한 안정된 배포 환경을 구축할 수 있게 도와준다는 점이 무척 신기했다!!
이번 실습을 통해 CI/CD의 구조와 흐름을 명확히 이해할 수 있었고, 앞으로 실무나 협업 프로젝트에서도 자신 있게 활용할 수 있을 것 같다.
하지만 이런 구축 방법은 CI/CD는 깃허브 계정 정보 노출에 대한 주의가 필요하다는 것을 알게되었다.
이번 실습에서는 EC2에서 GitHub 저장소에 접근하기 위해 Git ID와 토큰을 입력하고, 이를 저장해두는 방식을 사용했다.
이 경우 EC2 서버에 .git-credentials 파일이 생성되어 깃허브 계정과 토큰이 평문으로 저장되는 보안상 취약점이 생길 수 있다.
혼자 사용하는 개인 프로젝트라면 큰 문제가 되지 않을 수 있지만, 협업 환경이나 실서비스에서는 반드시 보안적인 고려가 필요하다.
다음 프로젝트에서는 팀 프로젝트에서의 CI/CD를 구축해보고자한다!
'Github Actions' 카테고리의 다른 글
| [Github Actions] Springboot 팀 프로젝트 CI/CD 구축하기 (0) | 2025.06.19 |
|---|---|
| [Github Actions] CI/CD를 구축해 자동 배포를 해보자. (0) | 2025.06.18 |
| [Github Actions] 배포 자동화, CI/CD란? (0) | 2025.06.18 |