리액트 앱 배포 자동화를 위한 전체 과정을 요약하여 정리했다.
각각의 인프라, 툴, 서비스들이 무엇이고 왜 사용하는지는 설명하지 않는다.
예전에 맨 위의 이미지로 그려놓았던 흐름을 보고 다시 해보았다
S3, CloudFront 사용을 위한 AWS 계정 설정.
S3 버킷 정적 호스팅을 위한 설정
Github-Actions 워크플로우 작성을 통한 배포 자동화 설정
Route53 설정
CloudFront 설정
액세스 키와, 비밀 키는 잘 보관해두도록 하자.
그리고 사실 Full-Access 보다는 특정한 버킷에만 접근할 수 있게 하는 것이 좋다!
ACL 활성화를 해준다
퍼블릭 액세스 차단을 해제 해준다
해제 후 버킷 만들기를 클릭!
생성한 버킷의 설정 탭에서 정적 웹 사이트 호스팅 항목을 찾는다.
정적 웹 사이트 호스팅 을 활성화 해주고 오류문서에도 index.html
설정을 해준다.
요거 안해주면 리액트의 다른 페이지를 못읽는다. SPA라 그렇다.
권한 탭에서 정책 편집 항목을 찾아 정책 생성기 클릭
정책 편집하기
붙여넣기
깜빡하고 ARN 뒤에 /*
을 안붙였따. 붙여주자
귀찮더라도 index.html
같은거 하나 넣어서 확인해보자!
앞으로 많은 과정이 더 있기 때문에
한 번에 다 해두고 에러 로그 확인하면서 어디가 터졌는지 찾기 귀찮다면 하나의 과정을 끝낼 때마다 확인해보는 것이 좋다.
변경이 발생할 때 마다 수동으로 배포하는 것은 매우 귀찮다.
오히려 지금 삽질하는데 드는 시간이 일정 기간 지나면 수동으로 배포하는 시간 보다 적게 들 것이다.
(1) 내 깃허브 리포지토리에 리액트 프로젝트 소스코드가 있다.
(2) 내가 원하는 브랜치에 코드가 반영되면 Github-actions로 감지시킬 수 있다.
(3) Github-actinos로 코드 반영을 감지하여 자체에서 제공해주는 서버에 리액트 앱을 빌드 한다.
(4) 빌드 결과물을 방금 만든 S3 버킷에 올린다.
(5) 자동으로 배포가 된다.
왜함
S3에 배포한다고 하였다.
내 S3 버켓은 나만 컨트롤 할 수 있어야 한다.
나(루트계정) 뿐 아니라 나(루트계정) 이 권한을 하사해준 다른 사용자 계정도 S3를 사용할 수 있다.
아까 S3권한을 포함시켜 생성했던 유저의 Access_id와 Secret_key를 우리는 가지고 있기 때문에
그 정보로 어디선가 S3를 컨트롤 할 수 있다.
그 정보를 Github-actions
에서 사용할 것인데 이 것은 노출되면 안되기 때문에
깃허브의 오픈 소스코드에 포함되서는 안된다.
리포지토리 설정에 등록하여 노출하지 않고도 사용할 수 있다.
Github Repository
의 Setting
=> Secrets and variables
=> Actions
클릭
ACCESS_KEY, SECRET_KEY, BUCKET_NAME을 필수로 하여 필요한 것들을 넣어준다.
.env
에 관리하고 있는 환경변수들도 넣어주자.
name: Build React App
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 16.x ]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Create env file
run: |
touch .env
echo REACT_APP_API_ENDPOINT=${{ secrets.REACT_APP_API_ENDPOINT }} >> .env
cat .env
- name: Npm Install
run: |
npm install
- name: Npm Build
run: |
npm run build
- name: Deploy to S3
uses: jakejarvis/s3-sync-action@master
with:
args: --acl public-read --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_STAGING_BUCKET_NAME }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
SOURCE_DIR: "build"
프로젝트 리포지토리 루트 경로에서 .github/workflows
폴더에 이 yml
파일을 넣어주자.
휴먼 에러가 없을리 없다. 보통 한 번에 안되니까 여유를 가지고 로그를 보며 원인을 파악하자
하다보면 ESLint에게 감사함을 느끼게 되는 일도 있고
이런 억까도 당하게 되니 마음 단단히 먹자!
워크플로우가 성공하면 앱 파일이 잘 들어갔는지 S3도 확인해보고 엔드포인트로 접속도 해보자
우선 Route53에서 도메인을 구매했다.
Route53에서 도메인을 구입하면 알아서 호스팅영역에 포함되지만
외부 도메인을 사용한다면 호스팅영역에 등록해줘야 하는 것 같다.
AWS Certificate Manager(ACM) 콘솔로 와서 인증서 요청을 시도하자
도메인 넣고 요청하면 된다. 어딘가에 사용하고 있는 도메인이 아닌지 확인하자.
해당 인증서 발급 상태 창으로 들어와서 Route53에서 레코드 생성하기를 클릭
Route53으로 와서 본인 도메인을 다시 살펴보면 CNAME으로 된 유형이 하나 생겼을 것이다.
레코드 이름
과 값/트래픽 라우팅 대상
이 ACM인증서에서 얻었던 CNAME 이름/값과 같은지 확인하자
밥을 먹고 오면 인증서 발급이 성공된다.
이제 우리는 SSL인증서가 발급된 이 도메인을 CloudFront에 붙일 것이다.
CloudFront 콘솔에서 배포 생성
을 클릭
원본 도메인 에 S3 호스팅 도메인을 넣는다**
뷰어 정책은 원하는대로 알아서 잘 설정하자 http => https redirect가 가장 좋은 방법이지 않을까
인증서와 도메인 을 연결한다.
사용자 정의 SSL인증서 에서 인증서 선택을 클릭하면 아까 만들었던 인증서가 나와야만 한다.
CloudFront 배포를 성공했다면 해당 배포 콘솔로 와진다.
무효화 탭을 클릭해 무효화 생성
을 클릭!
기본적으로 86400초 동안은 CloudFront에서 CDN에 캐싱 처리하는데
한 번 캐시되면 S3로부터 직접 애플리케이션을 읽지 않기 때문에
배포 자동화로 내 앱을 업데이트 해도 갱신이 안되는 골 때리는 상황이 생긴다.
우선은 전부 무효화 해주었다.
추후 필요한 부분들에 대해서만 무효화 설정해 CDN의 응답속도 이점을 잘 노리면 되지 않을까 생각한다.
오류 페이지 탭에 다음과 같이 설정해주자
spa라 해야하는 작업이다. 처음 메인페이지 들어가서 라우팅을 통해 페이지 이동을 하면 잘 들어가지지만
그 페이지(루트가 아닌)를 새로고침 해보면 왜 이걸 넣어야 되는지 알 수 있다.
A
레코드는 도메인이름에 IP주소를 직접 매핑해주는 방식인데
우린 아직 설정한적이 없었다.
CloudFront 주소를 우리가 만든 도메인에 매핑시켜주어야 한다.
좀 지나서 접속해보면 모든 과정이 끝났음을 알 수 있다.
어려운 부분은 없지만 각 AWS 서비스들 간 관계성이 꽤 밀접하고 복잡하여
한 과정을 해결할 때 마다 확인해보는 것이 좋을 것 같다
안녕하세요!! 유익한 글 먼저 너무 감사드립니다.!!
혹시 그럼 .env에 작성해둔 백엔드 api url도 전부 github action workflow에 작성하고 secret에 넣어주면 될까요?!