github actions를 통한 리액트 프로젝트 자동배포(react ,s3 ,cloudfront)

김철준·2024년 8월 12일
1

Devops

목록 보기
7/9

회사에서 프론트엔드 프로젝트는 리액트나 nextjs 프로젝트로 진행하고 있는데 항상 백엔드 개발자분들이 자동배포 구성을 해주셨다.

백엔드 개발자분들이 aws 관련해서 rdb,ec2,s3 등 셋팅을 해주시고 계셔서 자연스럽게 그렇게 된 것 같다.

하지만 찾아보니 자동배포 관련 설정을 하는 것이 그리 어려운 것은 아닌 것 같아 보여 최근에 사내에서 시작한 프론트 프로젝트를 직접 자동배포를 구성해보기로 하였다.

GPT 선생님과 함께 하니 금방 구성하였다.

YML 구성

먼저 yml 파일을 생성하여야한다.

.github > workflows > deploy.yml

프로젝트 최상단에서
1. .github 폴더를 생성한다.
2. .github 폴더 내부에 workflows 폴더를 구성한다.
3. workflows 폴더에 deploy.yml 파일을 생성한다.

yml 파일이란?

yml 파일은 YAML(YAML Ain't Markup Language) 형식으로 작성된 파일로, 주로 구성(configuration) 파일로 사용됩니다. 이 파일은 일반적으로 .yml 또는 .yaml 확장자를 사용합니다.

YAML의 역할

  • 구성 파일: YAML 파일은 주로 설정값이나 환경 변수를 정의하는 데 사용됩니다. 복잡한 데이터 구조를 간단하고 명료하게 표현할 수 있어 구성 파일로 많이 사용됩니다.
    (spring boot에서 port,api 기본 endpoint,aws 등등 환경설정 값들을 yml에서 설정하는 것을 확인할 수 있다.)

yml

spring:
  datasource:
    driver-class-name: ~~~~
    url:~~~
    username: ~~~
    password: ~~~

  jpa:
    open-in-view: true
    hibernate:
      ddl-auto: validate # fixed
    properties:
      hibernate:
        show_sql: true
        format_sql: true
        highlight_sql: true
        default_batch_fetch_size: 1000
    defer-datasource-initialization: true

  sql:
    init:
      mode: always

logging:
  level:
    org:
      hibernate:
        orm:
          jdbc:
            bind: trace

yml

server:
  port: 8080

spring:
  profiles:
    include: dev, aws, oAuth2, key, redis

  servlet:
    multipart:
      max-file-size: 30MB
      max-request-size: 30MB

api:
  base-path:
    client: /api/v1/client
    admin: /api/v1/admin

logging:
  level:
    com:
      amazons:
        util:
          EC2MetadataUtils: error
        internal:
          InstanceMetadataServiceResourceFetcher: error
  • 파이프라인 정의: YAML 파일은 CI/CD(Continuous Integration/Continuous Deployment) 도구에서 파이프라인의 정의를 위해 자주 사용됩니다. 예를 들어, GitHub Actions, Travis CI, CircleCI 등의 도구에서 작업을 정의하고 자동화하는 데 사용됩니다.

.github/workflows/deploy.yml 파일은 GitHub Actions에서 사용되는 파이프라인(workflow)을 정의하는데 사용된다고 한다. 이 파일에서는 특정 이벤트(예: 푸시, 풀 리퀘스트 등)가 발생할 때 자동으로 실행될 작업들을 정의한다.

따라서, 이 파일을 통해 GitHub 저장소에 특정 이벤트가 발생할 때마다 정의된 자동화된 배포 프로세스가 실행되도록 설정할 수 있습니다.

yml 파일을 어떻게 구성할까?

프로젝트의 최종적인 yml 파일 구성 코드는 다음과 같다.

이 deploy.yml 파일은 GitHub Actions를 이용해 리액트 프로젝트를 AWS S3에 자동 배포하고, CloudFront 캐시를 무효화하는 과정을 자동화하는 설정이다.

main 브랜치에 코드가 푸시될 때 자동으로 GitHub Actions를 통해 프로젝트를 빌드하고, AWS S3에 배포하며, CloudFront 캐시를 무효화하는 작업을 수행한다. 이를 통해 배포 과정이 자동화되어 일관성 있는 배포가 가능해진다.

deploy.yml

name: Deploy to S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '16'

      - name: Install dependencies
        run: npm install

      - name: Build project
        run: npm run build

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Deploy to S3
        run: aws s3 sync ./dist s3 주소(s3://~~~) --delete

      - name: Invalidate CloudFront Cache
        run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"

name: Deploy to S3

이름 설정: 이 워크플로우의 이름입니다. 이 이름은 GitHub Actions에서 이 작업을 구분할 때 사용됩니다. 여기서는 "Deploy to S3"로 설정되었습니다.

on: push: branches: - main

  • on은 이벤트 트리거를 정의하는 키워드입니다. on 키워드를 사용해 워크플로우가 언제 실행될지 설정합니다. 이 설정에 따라 특정 이벤트가 발생할 때 워크플로우가 자동으로 실행됩니다.

  • push: 코드가 푸시될 때 이 워크플로우가 실행됩니다.

  • branches: - main: main 브랜치에 푸시가 발생할 때만 이 워크플로우가 실행됩니다. 다른 브랜치에 푸시되면 실행되지 않습니다.

나의 경우, github 레포지터리에서 main을 배포 브랜치로 설정하여서 main에 푸시가 되면 자동배포가 되게 하려고 한다.

jobs: deploy: runs-on: ubuntu-latest

  • jobs 키워드는 워크플로우 내에서 어떤 작업을 수행할지 구체적으로 정의하며, 각 작업은 여러 단계(step)로 구성될 수 있습니다.

  • 작업(job) 정의: deploy라는 이름의 작업을 정의합니다. 이 작업은 리눅스 환경(ubuntu-latest)에서 실행됩니다.

  • GitHub Actions는 다양한 운영체제에서 작업을 실행할 수 있는데, 여기서는 최신 우분투 환경을 사용하도록 설정했습니다.

steps:

  • 단계 정의: 이 작업 안에서 수행할 여러 단계들을 정의합니다. 각 단계는 특정 작업을 수행합니다.

- name: Checkout code uses: actions/checkout@v3

  • 코드 체크아웃: 이 단계는 GitHub 저장소의 코드를 현재 워크플로우 실행 환경으로 가져옵니다.

  • actions/checkout@v3: GitHub이 제공하는 공식 액션을 사용해 코드를 체크아웃합니다.

- name: Set up Node.js uses: actions/setup-node@v3 with: node-version: '16'

  • Node.js 설정: 이 단계는 Node.js 환경을 설정합니다.

  • uses: actions/setup-node@v3: GitHub의 공식 액션을 사용해 Node.js를 설치합니다.

  • with: node-version: '16': Node.js의 버전은 16으로 설정됩니다. 이는 프로젝트가 이 Node.js 버전에서 실행될 것을 가정합니다.

- name: Install dependencies run: npm install

  • 의존성 설치: npm install 명령어를 사용해 프로젝트의 모든 npm 패키지들을 설치합니다.

  • 이 단계는 프로젝트를 빌드하기 전에 필요한 모든 패키지들이 준비되도록 합니다.

- name: Build project run: npm run build

  • 프로젝트 빌드: npm run build 명령어를 실행하여 프로젝트를 빌드합니다. 리액트 프로젝트의 경우, 이 명령어는 최종 배포용으로 최적화된 정적 파일을 생성합니다. 빌드 결과물은 일반적으로 ./dist 또는 ./build 디렉터리에 저장됩니다.

- name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1

  • AWS 자격 증명 설정: 이 단계에서는 AWS CLI와의 상호작용을 위해 AWS 자격 증명을 설정합니다.

  • aws-access-key-id와 aws-secret-access-key는 GitHub Secrets에 저장된 값들로, GitHub 리포지토리 설정에서 비밀로 관리됩니다.

  • aws-region은 AWS 리소스가 위치한 리전을 지정합니다. 여기서는 us-east-1로 설정되어 있습니다.

  • 이 액션을 통해 후속 단계에서 AWS 명령어를 사용할 수 있습니다.

- name: Deploy to S3 run: aws s3 sync ./dist s3://~~~ --delete

  • S3로 배포: aws s3 sync 명령어를 사용해 빌드된 파일들을 S3 버킷으로 동기화합니다.

  • ./dist는 빌드 결과물이 위치한 디렉터리입니다.

  • s3://는 배포할 S3 버킷의 경로입니다.

  • --delete 옵션은 S3 버킷에서 로컬에 없는 파일들을 삭제하여 S3 버킷과 로컬 디렉터리의 내용을 동기화합니다.

- name: Invalidate CloudFront Cache run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths "/*"

  • CloudFront 캐시 무효화: 배포 후 변경된 파일이 S3 버킷에 업로드되었음을 CloudFront에 알리고, 이전 파일들의 캐시를 무효화합니다.

  • aws cloudfront create-invalidation: CloudFront의 캐시를 무효화하는 명령어입니다.

  • --distribution-id: 무효화할 CloudFront 배포의 ID를 지정합니다. 이 값 역시 GitHub Secrets에 저장되어 있습니다.

  • --paths "/*": 모든 경로에 대한 캐시를 무효화하여 새로운 파일들이 제대로 반영되도록 합니다.

github에서 secrets 설정

위 yml에서 확인해보면

  • ${{ secrets.AWS_ACCESS_KEY_ID }}
  • ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  • ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }}

3가지들은 github 레포지토리로 이동하여 각각 설정해줘야한다.

1. 해당 깃헙 레포지터리의 설정 탭으로 이동한다.

2. 좌측 사이드바의 secrets and variables > Actions를 클릭한다.

3. 해당하는 secrets들을 생성해준다.

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • CLOUDFRONT_DISTRIBUTION_ID

이 키들은 aws에서 값들을 얻어와야한다.

aws 어디서 얻어와야하는지 알아보자.

AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY

위 두 값들은 aws IAM 서비스로 이동하면 값을 조회할 수 있다.

  1. IAM 서비스로 이동하여 좌측 사이드바에서 사용자를 클릭한다.

  1. 사용자가 없다면 사용자를 생성한다.

2.1 사용자 이름을 설정한다.

2.2 권한 옵션에서 직접 정책 연결을 선택한다.

2.3 권한 정책 중 AmazonS3FullAccess와 CloudFrontFullAccess를 찾아서 체크한 뒤 다음으로 이동하고 사용자 생성을 한다.


  1. 엑세스 키가 없다면 엑세스 키를 만들어야한다.

3.1 사용 사례에서 AWS 외부에서 실행되는 애플리케이션 옵션을 선택한다.

3.2 엑세스 키와 비밀 엑세스 키를 확인한다.

이 때 주의할 것은 비밀 엑세스 키(AWS_SECRET_ACCESS_KEY)는 생성시 해당 화면에서 한번만 확인할 수 있기 때문에 따로 어디 메모를 해놔 기억해야한다.

엑세스키 : AWS_ACCESS_KEY_ID
비밀 엑세스 키 : AWS_SECRET_ACCESS_KEY

위 값들을 깃헙 레포지터리 설정 > secrets and variables에서 설정해주자.

CLOUDFRONT_DISTRIBUTION_ID

CLOUDFRONT_DISTRIBUTION_ID는 CloudFront 배포의 ID이다.

aws cloudfront로 이동하여 ID값을 github에서 가서 설정하면 된다.

생각보다 간단?

위처럼 yml 구성 및 aws 키값을 깃헙에 설정하기만 하면 자동배포 설정완료다.
물론 지피티 선생님이 있었기에 순탄히 할 수 있었고 그리 어려운 일은 아니므로 앞으로 자동배포 작업은 왠만하면 내가 해두도록 해야겠다.

profile
FE DEVELOPER

0개의 댓글