
저번 시간에는 ec2 가상 머신에 nginx까지 올려보았다.
이제 본격적으로 yml 파일을 작성하여 CI 준비를 해보겠다.
우선, CI는 코드가 수정이 될 때마다 지속적으로 편하게 통합이 되어 빌드, 테스트를 하는 과정이라고 할 수 있다.
나는 main 브랜치에 새로 머지가 되면 CI/CD 파이프라인이 돌아 EC2에 서버가 배포될 수 있도록 할 계획이다.
우선 나는 express 프레임워크를 사용하여 개발하였기 때문에 ec2 인스턴스에 nodejs를 설치해주었다.
아래 명령어를 사용하여 nodejs를 설치하자.
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
그 다음으로 깃허브 액션에서 환경변수를 설정한다.
다들 알다시피 소스코드에 민감한 정보를 하드코딩하는 것은 보안상 매우 좋지 않으므로 ssh_key나 IP주소, DB URI 같은 것들은 전부 환경변수로 저장해 놓자!

위 사진처럼 New repository secret을 눌러 새로운 환경변수를 생성하면 되는데, 나는 EC2의 IP와 SSH의 private key를 환경변수로 지정했다.
private key를 저장할 때는 반드시
-----BEGIN RSA PRIVATE KEY-----
... 괴상한 문자열들
-----END RSA PRIVATE KEY-----
위와 같이 모든 내용을 전부 복사해야 한다.
문자열들만 해줬다가 에러로 흠씬 두들겨 맞음,,ㅜ
Github Actions는 Github가 해당 저장소에서 .github 폴더를 찾고, 그 내부의 yaml 파일들을 읽어들여 인식하고 실행한다.
그러므로 프로젝트 루트 경로에 .github 폴더를 만들고 바로 하위 폴더에 workflows 폴더를 만든다.
workflows 폴더 안에는 main-deploy.yml이라는 파일을 하나 만들 것이다.
요런 구조,,
이제 yml 파일을 작성해보자!
name: deploy-main
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "$EC2_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
cat >>~/.ssh/config <<END
Host app_name
HostName $EC2_IP
User $EC2_USER
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
END
env:
EC2_USER: ubuntu
EC2_IP: ${{ secrets.EC2_IP }}
EC2_SSH_KEY: ${{ secrets.EC2_SSH_KEY }}
- name: Copy Workspace
run: |
ssh app_name 'sudo mkdir -p /opt/app'
ssh app_name 'sudo chown ubuntu:ubuntu /opt/app'
scp -r ./[!.]* app_name:/opt/app
- name: Install dependencies
run: |
ssh app_name 'npm install --prefix /opt/app/'
- name: Install PM2 Globally
run: |
ssh app_name 'sudo npm install -g pm2'
- name: Start Application with PM2
run: |
ssh app_name 'pm2 start /opt/app/app.js --name "my-app"'
- name: Save PM2 Process List
run: |
ssh app_name 'pm2 save'
- name: Check PM2 Process List
run: |
ssh app_name 'pm2 list'
위에서부터 천천히 읽어나가보자면,
우선 main 브랜치로 코드가 푸시되었을 때 워크플로우가 실행되도록 작성하였다.
내 ec2는 ubuntu-24.04 환경에서 실행되기 때문에 해당 내용을 jobs에 작성해주고, 아래 steps부터는 job 내에서 수행할 개별 작업들을 작성해주면 된다.
ssh 키를 설정하여 EC2 서버에 접속할 수 있도록 설정한다.
chmod를 600으로 설정해야 권한 에러가 생기지 않으니 저 부분은 각별히 신경쓰도록 하자.
pm2를 -g 옵션을 사용하여 전역에 설치하자.
처음에는 pm2를 전역적으로 설치할 수 없다는 에러가 떠서,, 앞에 sudo를 붙여주니까 에러가 해결되었다..(매우 찜찜하지만,, 일단 돌아가니까;)

이렇게 배포가 완료되면 반드시 IP:PORT로 접속해서 잘 돌아가는지 확인해보자!!
예전에 해커톤에서 Github Actions는 잘 돌아갔으나 무슨 이유에서인지 배포가 잘 되지 않아 애를 먹었던 매우 슬픈 경험이 있기 때문에 반드시 잘 확인해보자..ㅜㅜ
이로써 험난했던 CI/CD 구축 도전기가 끝이 났다.
사실 지금도 main에 push를 할 때가 되면 행여나 예상치 못한 에러가 뜰까봐 심장이 뛰곤 하지만..
일반적으로 의존성 문제이거나 pm2의 PORT 충돌 에러긴 해서,, ec2 서버 상에서 npm run dev를 실행시켜서 직접 에러를 찾거나 pm2 logs로 에러 로그를 하나하나 뜯어보면 되기 때문에 점차 적응해나가는 것 같다.
확실히 직접 부딪쳐 보는 것이 두려움을 해소할 수 있는 가장 효과적인 방법이 아닐까 싶다.