Server

GitHub Actions를 활용한 React 애플리케이션의 EC2 배포

범데이 2024. 8. 9. 18:04
728x90

이 포스팅에서는 GitHub Actions를 사용하여 React 애플리케이션을 AWS EC2 인스턴스에 자동으로 배포하는 방법을 설명한다.

 

(이전 CI 포스팅에서는 Docker를 활용하여 CI/CD를 구성하려고 계획하였으나.. 사용하는 EC2의 자원으로는 턱없이 부족해서 컨테이너만 띄웠다 하면 인스턴스가 멍텅구리처럼 멈추는 현상이 발생했다. 그래서 그냥 빌드된 파일을 직접 nginx가 띄울수 있게 던져주기로..)

 

*시스템 환경

구성 일자: 2024-08-09
AWS EC2 Instance: Ubuntu 18.04
Local PC: Windows 10
React: 18.3.1

 

 


 

 

1. GitHub Actions를 활용한 배포

1.1 CD(Continuous Deployment) 워크플로우 설정

CD 워크플로우는 새로운 릴리스가 생성될 때마다 EC2 인스턴스에 애플리케이션을 배포한다. 아래는 `deploy.yml` 파일의 예시이다.

 

name: Deploy to EC2 on Release

on:
  release:
    types: [created]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x]

    steps:
    - name: Check out Git repository
      uses: actions/checkout@v4

    - name: Install Dependencies
      run: npm install

    - name: Build React app
      run: CI=false npm run build
      
    - name: Create version file
      run: |
        echo "VERSION=${{ github.event.release.tag_name }}" > version.txt
        echo "VERSION: ${{ github.event.release.tag_name }}" > ./build/version.txt
        
    - name: Copy files via SCP
      env:
        SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
        EC2_IP: ${{ secrets.EC2_IP }}
        EC2_USER: ${{ secrets.EC2_USER }}
      run: |
        mkdir -p ~/.ssh
        echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
        chmod 600 ~/.ssh/id_rsa
        scp -o StrictHostKeyChecking=no -r ./build/* $EC2_USER@$EC2_IP:/var/www/html/

 

 

각 단계 설명:

- Checkout Git repository: 레포지토리의 코드를 체크아웃한다.

- Install dependencies: 의존성을 설치한다.

- Build project: 프로젝트를 빌드한다.

- Create version file: Release시 설정한 버전 태그 정보를 파일로 저장한다.

- Copy files via SCP: 비공개 SSH키를 세팅하고, 빌드된 파일을 EC2 인스턴스의 지정된 디렉토리에 scp로 복사한다.

 

 

위의 `secrets.SSH_PRIVATE_KEY`, `secrets.EC2_IP`, `secrets.EC2_USER` 변수는 GitHub 레포지토리의 Secrets and variables > Actions 페이지에서 secret 변수로 추가해준다.

 

 

 

2. EC2 인스턴스 설정

2.1 SSH 키 설정

1. SSH 키 생성:

로컬 머신에서 다음 명령어를 실행하여 SSH 키 쌍을 생성한다.

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

 

 

 

2. 공개 키 추가:

- 생성된 공개 키(`id_rsa.pub`)를 EC2 인스턴스의 `~/.ssh/authorize_keys` 파일에 추가한다.

 

 

SSH 공개 키를 `authorized_keys`에 추가하는 방법:

 

1. EC2 인스턴스에 SSH로 접속:

ssh -i path_to_your_private_key.pem ec2-user@your_ec2_ip

 

 

2. `authorized_keys`파일 열기:

vi ~/.ssh/authorized_keys

 

 

3. 로컬 머신에서 공개 키 내용 복사:

공개 키 파일(`id_rsa.pub`)의 내용을 복사한다.

cat id_rsa.pub

 

 

4. 복사한 공개 키를 `authorized_keys` 파일에 붙여넣기:

`authorized_keys` 파일에 공개 키 내용을 붙여넣고 저장한다.

 

 

설명: `authorized_keys` 파일에 공개 키를 추가하면 해당 공개 키와 일치하는 비공개 키를 가진 사용자는 EC2 인스턴스에 SSH로 접근할 수 있다. 이는 보안 연결을 보장하고, GitHub Actions에서 EC2 인스턴스에 안전하게 접근할 수 있게 한다.

 

 

 

3. GitHub에서 릴리스 발행 및 배포 확인

1. GitHub에서 릴리스 발행:

- GitHub 레포지토리로 이동하여, `Release` 탭을 클릭한다.



- `Draft a new release` 버튼을 클릭하여 새로운 릴리스를 작성한다.

 

 

` 태그 버전 및 릴리스 제목을 입력하고, `Publish release`를 클릭한다.

 

 

 

2. 배포 확인:

- GitHub 레포지토리 Actions 의 workflow가 정상적으로 돌았는지 확인한다.

 

 

- EC2 인스턴스에 접속하여 웹 브라우저에서 애플리케이션이 올바르게 배포되었는지 확인한다.

  (Release시 tag에 입력한 버전 정보가 txt 파일로 저장되어 있다)

 

 

- Nginx 서버의 로그를 확인하거나, 애플리케이션이 업데이트된 내용을 확인하여 배포가 성공적으로 이루어졌는지 검증한다.

 

 

4. 트러블슈팅

4.1 scp 접근 key 검증 실패 오류

- 문제

`***@***: Permission denied (publickey).`

 

 

- 해결 방법

- "2.1" 순서의 SSH 키 설정에서 EC2 서버 내의 authorized_keys파일을 정상적으로 설정했는지 확인한다.

- 해당 파일이 정상적으로 설정되어야, 접근 시 사용하는 키 값을 대조하여 정상적으로 접근을 할 수 있게 한다.

 

 

4.2 scp permission denied 오류

- 문제

`scp: /var/www/html ... Permission denied`

 

 

- 해결 방법

- 디렉토리 권한 확인: `/var/www/html/` 디렉토리와 하위 디렉토리의 권한을 확인하고 필요한 경우 수정한다.

- 권한 수정: 로그인한 유저로 디렉토리에 파일을 쓸 수 있는 권한이 있는지 확인한다. 다음 명령어를 사용하여 권한을 수정한다:

sudo chown -R <USER_NAME>:<USER_NAME> /var/www/html
sudo chmod -R 755 /var/www/html

 

 

참고: `scp` 명령어를 사용할 때 EC2 인스턴스의 권한이 올바르게 설정되어 있어야 한다.

 

 


결론

이 포스팅에서는 GitHub Actions를 사용하여 React 애플리케이션의 EC2 배포를 자동화하는 방법을 설명했다. CD 워크플로우 설정, SSH 키 관리, EC2 인스턴스의 권한 설정 및 트러블슈팅 방법을 다루었다. 마지막으로 GitHub에서 릴리스를 발행하고 배포가 성공적으로 수행되었는지 확인하는 과정을 안내했다.

 

이를 통해 효율적인 배포 프로세스를 구축하고, 개발 및 운영의 자동화를 구현할 수 있다.

반응형

'Server' 카테고리의 다른 글

GitHub Actions + Docker로 CI환경 구축  (0) 2024.07.13
Stateless와 Stateful의 개념, 차이점  (0) 2022.07.16
Karaf에 대해  (0) 2022.07.16
온프레미스(On-premise)란?  (0) 2022.05.01
AWS EC2 서버에 Nginx를 이용해 Vue 배포하기  (0) 2022.04.25