
nodejs + express를 이용한 백엔드 프로젝트를 진행하다가 마주한 EC2 + Github Actions 적용 방법에 대해 이야기 해보고자 한다.
정말정말 많은 오류를 마주했고, 막상 해결하고 보니 정말 어이없는 오류였기에 나처럼 삽질하는 사람이 없으면 하는 마음에 글을 쓴다.
(모든 예제에서 my-app 대신 package.json에 있는 name을 사용하면 된다.)
workflow에 대한 yml 파일은 다음과 같이 작성하였고 대략적인 흐름은 다음과 같다.
checkout -> EC2에서 실행중인 폴더로 접근 -> 켜져있는 애플리케이션 모두 종료 -> git pull로 현재 브렌치 최신화 -> nodejs, npm 중 없는 것 설치 -> 의존성 설치 -> my-app에 대한 애플리케이션 시작
name: Node.js Dev CI/CD
on:
push:
branches:
- main
workflow_dispatch: # 수동 실행도 가능하도록 함
jobs:
deploy:
runs-on: ubuntu-latest # 우분투 최신 버전으로 실행
steps:
# Checkout the code
- name: Checkout
uses: actions/checkout@v3
# Deploy to EC2
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.AWS_EC2_HOST }}
username: ${{ secrets.AWS_EC2_USER }}
key: ${{ secrets.AWS_EC2_KEY }}
script: |
cd ~
cd my-app
npx pm2 stop my-app
git pull origin main
if ! command -v node &> /dev/null; then
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
fi
if ! command -v npm &> /dev/null; then
sudo apt install -y npm
fi
npm ci
npx pm2 start npm --name "my-app" -- start
on에 해당하는 부분을 위와 같이 작성한 이유는 stack overflow에서 첫 번째 답변을 보면 알 수 있다.
결국 main에 push가 되는 일은 dev -> main으로 merge가 되는 경우라고 볼 수 있다.
위 환경변수의 경우 퍼블릭 IPv4 주소를 작성해주면 된다.

user는 AWS에서 확인할 수 있다.
해당 프로젝트에서는 Ubuntu를 사용했기 때문에 user는 ubuntu이다.
여기에서 굉장히 삽질을 많이 했다..
AWS_EC2_KEY라는 값이라기에 현재 EC2에 대한 SSH key를 발급 받아야하나 했다.

그 결과 삽질을 얼마나 했는지.....
여기에서 요구하는 key는 EC2를 생성할 때 만들었던(혹은 존재하던) pem에 대한 정보였고, 이는 아래 명령어로 알 수 있었다.
cat "pem이 존재하는 경로"
그러면 아래와 같이 출력될 것이다.
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
BEGIN ~ END를 포함하는 값을 복사 후 AWS_EC2_KEY에 넣어주면 된다.
그러면 다음과 같이 workflow가 작동한다!!

바로 되면 재미없지
이번에는 npm: command not found가 맞이해준다. 이는 GPT를 통해 해결할 수 있었다.
if ! command -v node &> /dev/null; then
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs
fi
if ! command -v npm &> /dev/null; then
sudo apt install -y npm
fi
npm이 없다면 npm을 설치해주고, nodejs가 없으면 nodejs를 설치해주는 script를 추가했다.
이젠 진짜 됐다!!

어림도없지
action은 정상적으로 실행되지만 npm start로 인하여 터미널이 계속 켜져있는 상태이기 때문에 다음 step으로 넘어가지 못하는 상황이다. 이를 위해 pm2 라이브러리를 설치 후 현재 yml 파일과 같이 수정되었다.

드디어 성공
추가적으로 몇 가지 script에 대해 이야기하고자 한다.
pm2로 실행한 my-app의 인스턴스 모두를 종료하는 script이다.
my-app이라는 이름의 인스턴스를 pm2를 사용하여 실행시킨다.
새로운 프로젝트에 백엔드로 참여하게 되었는데, 생각보다 할것도 많고 모르는점도 많아서 힘든 것 같다. 이번 경험을 통해 백엔드의 고충을 느끼게 되었다.
AWS는 왜이렇게 어려운가