이번에 새로 시작하는 프로젝트에 CI,CD를 먼저 적용하여 편하게 개발을 하자고 의견이 나와 CI,CD작업을 수행했다.
백엔드의 경우 기존에 했던 작업 이 있어 쉽게 만들었다.
근데, 프론트의 경우 경험이 경험이 없어 프론트 담당분께 부탁드리고 도와 드리는 식으로 하려했으나 이쪽부분에 경험이 아예없으셔서 그냥 내가 직접 해보기로 했다.
여기를 참고해서 만들었고 오류가 발생했던 부분을 수정하여 배포를 하였다.
(ec2 인스턴스에 npm,node,yarn,pm2를 설치해야 하기에 위 링크를 참고해서 미리 설치해두자)
EC2인스턴스에 S3,CodeDeploy,Github action을 이용하여 배포를 하는 전반적인 과정은 백엔드와 같으므로 해당 부분은 여기를 참고해 미리 설정해야 한다.
그럼, AWS 설정을 다 마쳤다고 가정하고 시작해보자.
먼저 Github action에 등록할 yml파일이다.
name: Deploy
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-20.04
steps:
- name: Checkout source code. # Repo checkout
uses: actions/checkout@v2
- name: Check Node v
run: node -v
- name: Install yarn
run: npm install -g yarn
- name: Install dependency
run: yarn install
- name: Build
run: yarn build
env:
CI: ""
- name: zip create
run: zip -qq -r ./압축파일이름.zip .
shell: bash
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Upload to S3 # Upload build file to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp --region ap-northeast-2 ./압축파일이름.zip s3://버킷이름/압축파일이름.zip
- name: Code Deploy
run: aws deploy create-deployment
--deployment-config-name CodeDeployDefault.AllAtOnce
--application-name 코드디플로이 애플리케이션 이름
--deployment-group-name 배포그룹 이름
--s3-location bucket=버킷이름,key=압축파일이름.zip,bundleType=zip
주의 해야 되는 부분은 Build부분이다. 만약 CI값을 false로 설정하지 않으면 기본값이 true이기에 빌드과정에서 뜨는 warning을 Error로 여겨 빌드에 실패하게 된다. (""라고 써줘도 false로 된다)
그 외 값들은 백엔드 작업에서 했던 github workflow파일과 유사하기에 한글로 입력한 부분만 자신의 AWS 값에 맞게 넣어주면 된다.
secret부분이 뭔지 모르겠다면 여기를 참고하거나 Github Action secret 뭐 이런식으로 구글링 하길 바란다.
다음으로, appspec.yml이다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/testfe
overwrite: yes
permissions:
- object: /home/ubuntu/testfe
owner: root
group: root
mode: 755
hooks:
AfterInstall:
- location: build.sh
timeout: 1000
runas: root
이것도 백에서 했던 부분과 비슷하지만 좀 다른 부분이 있다.
우선, 권한을 root로 한다.
백에선 sudo를 사용하지 않고 그냥 배포를 하면 되었기에 ubuntu로 설정했지만
프론트의 경우 실행할 쉘스크립트 파일에서 sudo를 사용해야 하기에 root로 설정해야한다.
또, location부분에서 원래는 scripts 폴더를 만들어 사용했는데 이번엔 그냥 루트디렉토리에 만들어서 사용했다.
마지막으로 build.sh이다.
#!/bin/bash
REPOSITORY=/home/ubuntu/testfe
cd $REPOSITORY
sudo npx pm2 kill
sudo rm -rf node_modules
sudo yarn install
sudo npx pm2 start yarn --interpreter bash -- start
여기서 정말 고생했다;;
우선 참고했던 글에선 yarn install하고 npx pm2 reload all을 하면 배포가 끝나는데 난 그렇게 하면 배포가 되지 않았다.
그래서 직접 pm2 log를 열어보니 Error: Cannot find module '../scripts/start' 이런 오류가 떠있었다.
그 외에도 react-scripts와 관련된 오류가 계속해서 떴고 원인이 이해가 되지 않아 구글링 해보니 그냥 node_modules폴더를 지우고 다시 install을 하면 된다고 하길래 그렇게 했더니 install하다가 인스턴스가 굳어버렸다.
처음엔, install이 문제라고 생각해 다른방법을 열심히 찾아보고 시도해봤지만 아무 소용이 없었다. 그러다 문득 든 생각이 pm2로 백그라운드에서 서버가 계속해서 실행시도를 하는건가 싶어 top을 쳐보니 kswapd0란 놈이 cpu점유율을 거의 다 먹고 있었다.
얘는 리눅스의 가상메모리를 담당하는 프로세스이고 메모리가 부족해 SWAP메모리를 사용할 때 사용되는 프로세스라고 한다.
또, 메모리는 root 권한으로 ruby가 대부분을 잡아먹고 있었다.
그래서 바로 kill을 쳐보니 원래의 속도로 멀쩡히 돌아왔다..
뭔가 pm2를 실행중일때 node_modules를 삭제하고 다시 install하는 과정에서 순환적인 문제나 충돌이 발생해서 메모리만 잡아먹히고 race condition이 형성되어 있을 수 있다고 생각되어 이번엔 pm2 kill을 먼저 하고 node_modules를 삭제하고 다시 install을 해보았다.
결과는 성공이였다 프로젝트는 무사히 배포되었고 빌드하고 배포하는 과정이 다소 걸리긴 했는데, 이 부분은 나중에 다시 고려해봐야 할 것 같다..
!!!
인스턴스가 뻗어버리는 이유를 알았다..
그냥 백엔드 서버랑 프론트 서버를 둘다 배포하면 freetier 메모리가 부족해서 뻗어버리는거였다..
한 ec2인스턴스에 둘 다 넣는건 안될 것 같다..
이 글을 보니 가상 메모리를 추가하는 방안이 있어 해당 방법을 따라 해보니 편안하게 동작한다..!
참고
https://svrforum.com/develop/67872
'DevOps' 카테고리의 다른 글
서버에 wss연결을 해보자 ( Nginx, Https, wss) (0) | 2023.05.25 |
---|---|
리액트는 무슨 웹서버를 이용해서 호스팅 될까? (0) | 2023.05.05 |
[Github actions, secret]github workflow로 배포 시 json 파일 추가하기 (0) | 2023.04.29 |
[AWS RDS] 로컬에서 RDS 연결이 안된다..! (0) | 2023.04.29 |
Github secret으로 배포용 application.yml 암호화 하기 (0) | 2023.04.17 |