S3 서버
CI/CD를 적용하기 이전에 배포할 서버부터 만들어야 한다. 배포 서버는 S3를 이용하도록 하겠다.
S3관련해서 글을 정리할려고 했지만 이 글 만큼 정리가 잘 되어있는 글은 없는 것 같다.
S3배포가 마치면 CI/CD도 설정하러 가보자
CI/CD
CI/CD는 Continuous Integration / Continuous Deployment의 약자이다.
지속적 통합과 지속적 배포가 하나가 되어야 하기에 자동 배포로만 이해했다면 반만 이해했다고 볼 수 있다.
Github Actions라는 너무 좋은 기능이 나와서 대부분 요즘에는 이것을 사용하는 것 같다.
CI/CD가 이론적으로 무엇인지 궁금하다면 이 글을 참고해보자.
Github Actions 사용해보기
여기 있는 1,2편이 많은 도움이 되었다. 1편은 workflow의 기능들을 소개하고 2편은 실습편이다.
두번째로 scp(secure copy) 명령어로 workflow를 작성한 글도 매우 흥미로웠다. 이것도 1,2편 둘 다 보는 걸 추천한다.
workflow.yml을 작성하다가 checkout이 뭔지 궁금할 수도 있는데, 그럴땐 다음 글을 보자.
checkout은 깃허브 레포의 코드들을 내려받기위해서 깃허브에서 지원하는 액션의 익스텐션같은 느낌이다.
내가 작성한 workflow 파일의 내용이다.
name: Test deploy # Workflow 이름
on: # Event 감지
push:
branches:
- main
jobs: # Job 설정
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code. # Repo checkout
uses: actions/checkout@v3
- name: Check Node v # Node v 확인
run: node -v
- name: Install dependencies # 의존 파일 설치
run: npm install
- name: Generate build # React Build
run: npm run build
- name: Deploy # 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 --recursive --region ap-northeast-2 build s3://${s3 버킷 이름}
npm을 사용하는 경우이지만 yarn을 사용한다면 맞춰서 변경해주면 된다.
- name: Install Dependencies # 의존 파일 설치
run: yarn install --frozen-lockfile
- name: Build # React Build
run: yarn build
번들러를 vite를 쓴다면 deploy 명령어에 작성해야할 빌드 폴더가 build가 아니라 dist가 될 것이다.
aws s3 cp --recursive --region ap-northeast-2 dist s3://${s3 버킷 이름}
🙋♂️ yarn install --frozen-lockfile이 뭔가요?
ci환경에서 사용하는 명령어인 npm ci의 yarn 버전 명령어라고 생각하면 됩니다.
yarn install --immutable --immutable-cache --check-cache으로도 동일한 작동이 가능합니다.
npm ci란? 그렇다면 yarn은? : https://duck-blog.vercel.app/blog/web/npm-ci-do-how-about-yarn
npm ci? yarn ci? : https://velog.io/@cjy0029/npm-ci-yarn-ci
Github Actions에 환경변수 적용하기
repo에 들어가서 settings의 secret탭에서 환경변수를 추가할 수 있다.
s3 버킷을 생성하면서 받은 어세스 키와 시크릿 키를 추가해놓았다.
이렇게 추가한 키는 workflow에서 다음과 같이 사용할 수 있다.
- name: Deploy # Upload build file to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
.env 파일 생성하기
배포가 정상적으로 돌아가려면 AWS 키 뿐만 아니라 .env로 관리하고 있는 환경변수도 추가가 되어야 할 것이다. 하지만 github상에는 .env를 업로드하지 않았을 것이다. 그럴때도 secrets를 이용하면 된다.
프로젝트 상에서 카카오 인증 api 키와 base url, api url에 대한 환경 변수도 추가해주었다.
🙋♂️ Environment secrets와 Repository secrets, Organization secrets 무엇이 다른가요?
같은 환경 변수 이름을 사용했을 때 오버라이드 되는 방식을 가지고 있습니다.
Environment > Repository > Organization 순으로 우선순위입니다.
예를 들어서 Environment secrets와 Repository secrets가 동일한 변수명을 가지고 있을 때 Environment secrects가 우선시됩니다.
각각의 영역과 우선순위가 다르기 때문에 넓은 영역에서 사용이 필요한 환경변수라면 유의해서 설정해주어야 합니다. >> https://youtu.be/tXv_npAP90k
이제 github actions 동작시에 .env 파일을 생성하도록 작업을 추가해주면 된다.
# Github Repository Secrets를 통해 환경 변수 파일을 생성합니다.
- name: Generate Environment Variables File for Production
run: |
echo "REACT_APP_BASE_URL=$REACT_APP_BASE_URL" >> .env.production
echo "REACT_APP_API_URL=$REACT_APP_API_URL" >> .env.production
env:
REACT_APP_BASE_URL: ${{ secrets.REACT_APP_BASE_URL }}
REACT_APP_API_URL: ${{ secrets.REACT_APP_API_URL }}
echo명령어를 이용해서 .env파일을 생성해주면 된다.
>> 를 사용하면 파일이 존재하지 않으면 생성하고 파일이 존재한다면 다음 행에 추가하는 식으로 동작하게되면서 하나의 .env파일을 완성하게 된다.
🙋♂️ 환경변수가 너무 많은데 하나하나 추가해야하나요? 나중에 변수가 추가될 때도 그때마다 추가하나요?라는 의문이 들었다면 당신은 개발자가 맞습니다...다음의 명령어로 동적인 방법으로 .env 파일을 추가해줄 수 있습니다.
- name: Create .env file run: | jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' <<< "$SECRETS_CONTEXT" > .env env: SECRETS_CONTEXT: ${{ toJson(secrets) }}
환경변수가 여러개일 때도 추가될 여지가 많을때도 유용하겠죠?
>> https://ji5485.github.io/post/2021-06-26/create-env-with-github-actions-secrets/
Github Actions 따라가기
Actions에 들어오면 workflow를 작성할 수 있다. set up a workflow yourself라는 작은 파란색 글씨를 선택한다.
파일이름과 내용을 수정해서 커밋하면 된다.
우측에 document로 사용법도 설명하고 있으니 참고하자.
규칙을 main 브랜치에 push될 때로 설정해놓았으니 pr merge를 해준다.
후에 Actions에 들어가면 workflow에 맞게 실행되는 모습을 볼 수 있다.
build 과정에 문제가 없다면 완료된 화면을 볼 수 있다.
이제 버킷의 웹사이트 엔드포인트로 접속하면 배포가 된 것을 확인할 수 있다.
'react' 카테고리의 다른 글
[React] React 배포하기 (EC2, S3) (0) | 2023.01.05 |
---|---|
[Vite] vite로 이유 모르게 웹소켓 통신이 안되는 경우(ws, sockjs) (1) | 2023.01.05 |
json-server 커스텀하기 (0) | 2022.12.19 |
[React] Lifecycle과 메소드 그리고 Hook (0) | 2022.12.12 |
[React] Redux-toolkit 입문하기 (0) | 2022.12.10 |