All that I've dreamed of

[Github Actions] React + S3 + CloudFront 자동배포 (+ env 환경변수) 본문

ETC

[Github Actions] React + S3 + CloudFront 자동배포 (+ env 환경변수)

_베토디 2023. 1. 8. 02:17
반응형
현재 프로젝트 세팅은요...

 

S3 + Cloudfront 배포 + 도메인 설정까지 끝난 상태 ➡️ CloudFront 서브도메인 설정

React 환경변수로 개발/배포 env 파일 분리해 놓은 상태 ➡️ React  개발/배포환경 evn 파일 분리

 

하고 싶은 자동배포화는요...

 

📌 main 브랜치에 push 하면 react 빌드 -> S3 업로드 -> CloudFront 캐시무효화 및 배포

📌 배포시에는 .env.production 파일을 사용

 

 

1. 배포자동화를 할 Git Repository에 환경변수를 등록해 준다

 

push 할 Repository - Settings - Secrets - Actions 에 New Repository secret 을 등록한다

 

AWS_ACCESS_KEY_ID  :  AWS IAM 등록시 발급된 액세스키

AWS_SECRET_ACCESS_KEY : AWS IAM 등록시 발급된 시크릿 액세스키

AWS_REGION :  S3 버킷이 등록된 리전 ex) ap-northeast-2

DEV_AWS_S3_BUCKET :  S3 버킷이름

DEV_AWS_DISTRIBUTION_ID : CloudFront 배포ID (Cloudfront 콘솔에서 확인)

 

(.env.production 에 등록한 환경변수들) * 별도의 env 파일을 사용하지 않으면 생략

REACT_APP_HOST

REACT_APP_REDIRECT_GOOGLE

REACT_APP_REDIRECT_KAKAO

REACT_APP_REDIRECT_NAVER

 

2. yml 스크립트 작성

React 프로젝트 내에 .github/workflows 폴더 생성 후 deployment.yml 파일 생성 

 

name: deployment

on:
  push:
    branches:
      - main   

jobs:
  build:
    runs-on: ubuntu-latest   
    strategy:
      matrix:
        node-version: [16.x]   

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

      - name: Set up Node.js 
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}


      - name: Setting .env
        run: |
          echo "REACT_APP_GOOGLE_CLIENTID=$REACT_APP_HOST" >> .env.production
          echo "REACT_APP_API_DOMAIN=$REACT_APP_REDIRECT_GOOGLE" >> .env.production
          echo "REACT_APP_KAKAO_REDIRECT=$REACT_APP_REDIRECT_KAKAO" >> .env.production
          echo "REACT_APP_KAKAO_CLIENTID=$REACT_APP_REDIRECT_NAVER" >> .env.production
          cat .env.production

      - name: Install dependencies
        run: npm install

      - name: Build
        run: CI="false" npm run build

      - name: 빌드파일위치
        run: pwd

      - 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: Deploy to S3
        run: aws s3 sync ./build s3://${{ secrets.DEV_AWS_S3_BUCKET }} --delete

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

 

2-1. 

on:
  push:
    branches:
      - main

main 브랜치에 push 할 때 실행

 

2-2. 

 

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16.x]

프로젝트가 node v16.15.1 버전이라 node-version: [16.x] 로..

 

2-3

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

      - name: Set up Node.js 
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

실제 빌드와 배포가 이루어지는 steps 단계

name은 workflow 의 단계별 이름이니까 본인이 보기 편한대로 써주면 된다

actions/checkout@v3 은 간단히 이해하기로는 레파지토리에 올린 코드들을 가져오는 것
(실제로는 매우 복잡한 과정을 저 한 줄로 해결해 준다)
처음에 actions/checkout@v2 로 했더니 에러가 발생하길래 
actions/checkout@v3 으로 변경했다.
✔️참고 checkout 
 
 
actions/setup-node@v2로 쓰면 다음과 같은 경고 나올 수 있음 대충 최신 버전 쓰라는 뜻

 

✔️참고 setup-node

https://github.blog/changelog/2022-09-22-github-actions-all-actions-will-begin-running-on-node16-instead-of-node12/

https://github.com/actions/setup-node

 

2-4 환경변수 env 파일 세팅

  - name: Setting .env
    run: |
      echo "REACT_APP_GOOGLE_CLIENTID=$REACT_APP_HOST" >> .env.production
      echo "REACT_APP_API_DOMAIN=$REACT_APP_REDIRECT_GOOGLE" >> .env.production
      echo "REACT_APP_KAKAO_REDIRECT=$REACT_APP_REDIRECT_KAKAO" >> .env.production
      echo "REACT_APP_KAKAO_CLIENTID=$REACT_APP_REDIRECT_NAVER" >> .env.production
      cat .env.production

react 프로젝트 내에 있는 .env.production 는 gitignore 에 등록되어 repository 에 올라가지 않기 때문에

github actions 가 빌드할 때 환경변수를 못 찾아서 (.env.production 파일을 못 찾아서) 오류가 난다

 

So, 빌드 전 env 파일을 만들어 준다. (env 파일이 없다면 이 부분은 넘어가도 됨)

이미 github settings에서 등록한 변수들을 적용해 준다.

나는 .env.production 파일을 사용하므로 >> .env.production 으로 해주었다.

그냥 .env 파일을 사용한다면 >> .env 로 해주면 된다

 

✔️참고 Secrets 을 통해 env 파일 만들기

https://ji5485.github.io/post/2021-06-26/create-env-with-github-actions-secrets/

 

2-5

  - name: Install dependencies
    run: npm install

  - name: Build
    run: CI="false" npm run build

필요한 dependencies 를 설치하고 빌드를 수행하게 되는데

run: npm run build 로만 명령어를 쓰면 자꾸 빌드에서 에러가 발생했다.

열심히 구글링을 해봤더니 process.env.CI = true 로 되어있으면 warning 도 에러로 인식해서 안된다는 것 같았다..

그래서

run: CI="false" npm run build 로 바꿔주었더니 빌드까지도 잘 진행된다
 
✔️참고 CI 에러 날 때...
 

2-6

 
  - 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: Deploy to S3
    run: aws s3 sync ./build s3://${{ secrets.DEV_AWS_S3_BUCKET }} --delete

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

 

run: aws s3 sync ./build s3://${{ secrets.DEV_AWS_S3_BUCKET }} --delete

위 명령어는 github acions 가 빌드한 결과와 S3버킷을 동기화 한다는 뜻이다

 

(aws cli) $ aws s3 sync <source> <target> [--options]

 

yml 파일에

      - name: 빌드파일위치확인
        run: pwd
 
를 추가해 현재위치를 확인해 보고 빌드폴더가 어디있는지 확인해 보면 된다
동기화할 폴더가 ./build가 아니라면 확인해 보고 <source> 자리에 자기 파일위치를 넣어주면 된다
 
 
--delete 옵션의의미 :
--delete (boolean) Files that exist in the destination but not in the source are deleted during sync.
새롭게 빌드한 내용엔 없는데 현재(동기화 전) s3 객체에는 있는 파일들을 삭제한다는 뜻
 
✔️참고 S3 sync (객체동기화)
 
✔️참고 S3 sync 옵션들
 
 
 
S3 객체의 내용이 변경되면 CloudFront 는 반드시 캐시무효화를 해줘야 한다. (안하면 변경 전의 캐시 내용이 계속 나옴..)
 
run: aws cloudfront create-invalidation --distribution-id ${{secrets.DEV_AWS_DISTRIBUTION_ID}} --paths "/*"
 
위 명령어는 CloudFront 의 캐시무효화를 하는 명령어이고 대상이 될 CloudFront 배포ID를 적어주면 된다
옵션인 --paths "/*" 는 S3 객체 전체 캐시를 무효화 한다는 뜻. 
특정 폴더나 파일의 캐시만 무효화 하고 싶다면 "/example-path/example-file.jpg" 이런식으로 써도 된다.
 
✔️참고 캐시무효화 명령어, 옵션 관련

 

 

 

github actions 배울 때 열심히 해 볼걸...

오류 많이나고 뭔가 무서워서 외면했었는데 결국 시도해 보게 되었다.

정말 수많은 오류가 있었지만 ㅠㅠ 훌륭하신 블로거 분들과 aws docs 의 도움으로 아주 간단한 배포화지만 성공해서 다행이다

🥲

 

Comments