⚠️ 이전에 개발하고 있던 딜레마 카페 글 아닙니다...!
개요
CI/CD 도입 배경
이전에 개발하고 있던 개인 프로젝트인 딜레마 카페는 잠시 중단하고, 웹 개발 외주(어디인지는 보안상의 문제로 기재하지 않겠다.)를 받아 이를 진행하고 있다. 네이버 지도 API를 넣기 위해 일시적으로 배포를 진행했는데, 이 배포 과정을 매번 할 생각을 하니 꽤나 귀찮겠다는 생각이 들어 CI/CD(Continuous Integration/ Continuous Deployment)를 도입했다.
현재는 좀 위험한 CI/CD
배포나 테스트를 자동으로 진행할 수 있어서 CI/CD를 도입하는데, 나는 우선 내가 올린거는 바로바로 반영이 되게끔 설정을 해놓았다. 지금 내가 해놓은 방식은 굉장히 위험한 방식이긴 하다. 현재로써는 잘못된 파일을 검증하는 방법이 없기에 main 브랜치에 올라가는 모든 파일이 배포가 가능하다면, 바로바로 배포된다.
이는 꽤 위험한 작업이니 추후에 브랜치를 나누어 이를 막을 예정이다. 현재는 main 브랜치에 모두 들어가지만 추후에는 dev 브랜치를 파고, dev 브랜치를 검증 후, main 브랜치에 합칠 때 배포가 되게끔 설정할 예정이다.
Firebase Hosting + Github Action
기술 선택의 이유
나는 Firebase Hosting과 Github Action으로 CI/CD를 구축했다. ▼
이 둘을 선택한 이유는 친숙해서이다. 빠르게 개발하고 빠르게 배포해야하는 이번 프로젝트 특성상 새로운 기술을 충분히 학습할 시간이 없었다. 친숙한 것도 있지만 빠른 것도 있다. 굉장히 쉽고 설정할 것들이 적어, 대부분의 것들이 블랙박스로 처리되어있어 복잡한 구조가 아닌 이상 기본적인 요구는 빠르게 만족시킬 수 있다. 현재의 프로젝트 역시도 복잡한 구조 없이 페이지가 배포되는 것 정도에서 그치기 때문에 위의 두 기술을 선택했다.
Firebase Hosting
우선은 가장 먼저 Firebase Hosting부터 설정했다. Firebase Hosting을 하는 방법은 문서도 많고, 정리해놓은 블로그도 많아서 여기서는 크게 다루지 않겠다. ▼
몇몇 블로그 글을 보니 배포 할 때 firebase 관련 라이브러리를 프로젝트에 넣고 App.js에서 초기화를 해줘야한다고 되어있는데, firebase 데이터베이스를 사용하는게 아니라면 프로젝트에 CLI 툴로 설정만 해주면 된다. 프로젝트에 firebase를 초기화해서 넣어줄 필요는 없다. 그래서 내 프로젝트는 firebase 초기화 없이 아래와 같이만 되어있다. 물론 CLI로 설정은 해주었다. ▼
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import GlobalStyle from './components/ui/GlobalStyle.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<GlobalStyle />
<App />
</React.StrictMode>
);
Github Secrets
다음으로는 Secrets를 통해 .env에 있는 값과 firebase 키를 넣어주었다. 레포지토리 세팅에 들어가면 Security 항목에 Secrets and variables라는 탭이 있는데, 여기서 Actions로 들어가면 secret 키를 넣을 수 있다. ▼
나는 우선 네이버 지도 API도 사용하고 있기에 아래와 같이 키들을 넣어주었다. 이 키들은 뒤에 설정할 Github Action에서 사용하게 된다. ▼
GitHub의 환경 및 리포지토리 시크릿의 차이점
해당 탭에 들어가보면 Repository secrets 말고도 Environment Secrets 이라는게 존재한다. 처음에 Environment Secrets를 보게 되면,
'어? 내가 저기에 넣은 Key들은 .env 파일에 있던건데? 그러면 Environment Secrets에 설정해야하는게 맞지 않나?'
하는 생각이 들 수 있다. 그래서 둘의 차이를 간단하게 알아보면 이렇다.
Repository secrets
- 적용 범위: Repository 전체에 적용된다.
- 사용 방식: 해당 Repository 내의 모든 워크플로우 및 작업(job)에서 사용할 수 있다.
- 설정 위치: Repository 설정(Settings) 페이지에서 설정할 수 있다.
- 특징: Repository secret은 리포지토리 내의 모든 환경(environment)에서 접근 가능하다.
Environment Secrets
- 적용 범위: 특정 환경에만 적용된다.
- 사용 방식: 특정 환경에 배포(deployment)되거나 해당 환경에서 실행되는 워크플로우 및 작업에서만 사용할 수 있다.
- 설정 위치: 리포지토리의 환경(Environment) 설정 페이지에서 설정할 수 있다.
- 특징: Environment secret을 사용하면 같은 리포지토리 내에서도 환경별로 시크릿을 다르게 설정할 수 있어, 더 세밀한 보안 관리가 가능하다.예를 들어, 개발 환경과 프로덕션 환경에서 다른 API 키를 사용할 수 있다.
즉, 둘은 범위의 차이이지 사용 용도의 차이가 아니기 때문에 현재와 같이 전역적으로 적용한다면 Repository secrets를 사용하는 것이 낫다.
Github Actions
Secrets까지 다 설정했다면 다음으로는 Github Actions를 설정했다. 설정이라기에는 스크립트를 짰다. `.github` 디렉토리 안에 `workflows` 디렉토리를 만든 후, `firebase-hosting.yaml` 이라는 이름과 확장자로 스크립트를 만들었다. ▼
원하는 자동화 흐름
현재는 복잡한 자동화가 필요하지 않은 상태다. 단순히 main 브랜치에 코드가 merge/push가 되면 업데이트 된 코드를 자동으로 빌드해서 배포하는 것이 현재의 목표다. 그래서 이를 실현하고자 아래와 같이 스크립트를 작성했다.
name: Firebase Hosting CI/CD
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Build project
run: npm run build
env:
VITE_APP_API_KEY: ${{ secrets.VITE_APP_API_KEY }}
VITE_APP_NCP_KEY: ${{ secrets.VITE_APP_NCP_KEY }}
- name: Install Firebase CLI
run: npm install -g firebase-tools
- name: Deploy to Firebase Hosting
run: npx firebase deploy --only hosting --project eonedu-4dc21
env:
FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
steps에 있는 과정을 하나씩 보면 이렇다.
- 레포지토리에 있는 프로젝트를 가져온다.
- 이를 빌드 해 줄 node.js를 설정한다.
- 프로젝트의 의존성들(라이브러리, 프레임워크 등등)을 설치한다.
- 프로젝트를 빌드한다.
이 때 로컬에서 .env 파일의 내용을 읽고 API를 사용하기에 secrets에 있는 값들을 기반으로 .env 파일을 만든다. - Firebase CLI를 설정한다.
- Firebase Hosting으로 배포한다.
이 때 Firebase token이 필요하므로 secrets에 있는 토큰을 사용한다.
위의 순서대로 github action 스크립트를 작성했고, 이제 main branch에 코드가 반영될 때 마다 자동으로 빌드/배포가 진행된다. ▼
마치며
처음에는 CI/CD가 굉장히 어렵고 고난이도 기술이라고 생각했다. 이름부터가 뭔가 되게 테크스럽고? 하는 것도 자동화, 빌드, 그리고 처음 접하는 사람들은 알아듣기 어려운 용어들이 꽤나 많아서 처음 들었을 때는 거의 마지막에 배우는 그런 기술이라고 생각했다. 하지만 막상 해보고 나니 별 거 아니었다. 그냥 시키는 대로 해주면 되고, 양식도 자료도 많아서 검색하면서 하면 금방 진행할 수 있었다. 물론 조금 더 복잡한 스크립트를 짜게되면 그때는 아마 정신을 못차리고 몇날 며칠을 붙잡고 있겠지만, 이렇게 간단한 한 가지 동작을 하는 CI/CD는 누구나 시작할 수 있다고 생각한다.
이 글을 작성하는 현 시점, 리액트를 배운 지 한 달도 안됐어서 CI/CD를 배우느라 시간 다 가는거 아닌가? 했는데 하루면 충분히 적용할 수 있으니 겁먹지 말고 해보는걸 추천한다. 화이팅이다.
'Develop > React' 카테고리의 다른 글
[React][개발기] 10. 무한 슬라이드 개발 (0) | 2024.07.23 |
---|---|
[React][개발기] 9. 리팩토링과 총 점검 (0) | 2024.07.19 |
[React][개발기] 8. Login 모달, 그리고 전체 점검의 필요성 (0) | 2024.07.18 |
[React][개발기] 7. RoutePaths, NavBarData 등 데이터를 효율적으로 (0) | 2024.07.17 |
[React][개발기] 6. Stateless하기 만들기, 페이지 만들기, 그리고 Map 활용 (0) | 2024.07.17 |