길고 길었던 Goorm Deep dive 부트캠프 수료한지 약 2개월가량 지났고 수료식때 발표했던 bovo 프로젝트(독서기록 공유 모바일 웹)의 기능이 어느정도 완성되었다. 팀 구성원 각자가 본인의 사정에 따라 프로젝트의 refactoring 진행 속도가 부트캠프 진행중일 때보다 늦어짐에 따라 일단 배포를 하고 점진적으로 refactoring을 하는 것이 더 좋겠다는 판단이 들었다. 이러한 의견에 다들 동의해주었고 이에 따라 배포를 진행하려 했다.
그동안 내가 배포까지 주도하여 진행된 프로젝트는 전무했고, 여러 배포 플랫폼을 찾아보았는데, 대표적으로 Vercel, AWS S3, Google Cloud Platform, Netlify 등이 존재했다.(이보다 더 많겠지만 가장 많이 보이는 것들을 언급했다.) google trend로 조사해본 결과 대체적으로 Vercel과 AWS S3가 지배적인 것으로 보인다.
어떤 블로그의 글을 읽어보니 대형 IT 회사들은 대부분 자사의 platform을 활용해 배포를 진행하거나 AWS를 활용하여 배포를 하고 있었다. 그 이유를 생각해보았을 때 AWS 내에서는 정말 다양한 서비스를 제공하고 있어 확장성, 유연성, 보안 등에 이점을 가지기 때문이라 생각했다.
bovo 프로젝트는 현재 Github repo 상 서버의 repository와 화면의 repository가 분리되어 있으며, 서버는 이미 AWS EC2를 활용해 배포를 진행한 상황이었다. 프론트엔드 쪽에서 배포한다면 AWS S3로 배포하는 것이 적절하다고 생각했다. 왜냐하면 확실히 AWS 내 자체 서비스들이다 보니 연동성 면에서 이점을 가져갈 수 있을 것이라 생각했고 뿐만 아니라 CloudFront를 활용하여 정적 리소스(이미지)를 CDN을 활용하여 성능 최적화한다면 성능 부분에 대해서도 이점을 가져갈 수 있을 것이라 생각했기 때문이다.
다만 실배포를 AWS S3로 가져가되 다른 대안도 필요했다. 모든 팀원들이 프로젝트 배포된 화면을 확인하고자 했기에 프리티어 요금제 사용량 제한으로 인해 무리가 있을것으로 생각했다.
구글에 AWS 프리티어를 검색해보면 AWS 사이트에서 각 서비스별로 사용량 혹은 사용기간 제한을 확인할 수 있다.

위처럼 AWS S3의 경우 스토리지 용량이 5GB 제한이 있는 것을 확인할 수 있다.
또한 2만 건의 GET 요청, 2,000건의 PUT, COPY, POST 또는 LIST 요청, 100GB의 데이터 송신을 제공한다고 설명에 첨부되어 있다.
VITE의 roll up dundle analyzer를 통해 확인해보았을 때 root의 render size가 2.2MB로 이미지를 따로 분리해서 올린다해도 용량 제한에는 걸리지 않겠지만, 데이터 요청 건수가 마음에 걸렸다. 서버 팀원쪽에서도 화면을 직접 확인해보고 싶어하는 것으로 파악되서 팀원 7명이 얼만큼 데이터 요청을 보낼지 추정이 되지 않아 혹시나 싶은 마음이 들었다. 따라서 실 배포와 테스트 용도의 배포를 나누어서 진행하고자 했다.
Vercel의 경우 NextJS를 개발한 회사에서 제공하는 서비스라 ReactJS와도 연결이 잘 될것이라 생각되지만, 한가지 제약이 존재했다. 개인 repository에 한해서는 무료 배포(Hobby)가 가능하지만, Github의 repository가 Organization으로 조직된 경우 Pro mode(유료)로 진행할 수 밖에 없다. 물론 Pro trial이라해서 2주 무료 체험판이 존재하지만, 지속해서 코드를 수정해 나갈 상황을 보면 적절치 않은것으로 생각된다.
이에 따라 자연스럽게 Netlify를 생각하게 되었다. Netlify 역시 장점도 있지만 제약이 없는 것은 아니다. GUI 형식의 빠른 배포가 가능하지만 이 서비스는 build 시간에 제약이 있다. build 시간이 월 300분, bandwidth(대역폭)이 100GB에 제한이 있다. 다만, AWS에 비해 bandwidth 용량제한이 넓기도 하고, test 용도로 쓰기에 적합한 것으로 판단됐다.
그런데 흔히들 AWS S3, Vercel, Netlify에 대해 정적 웹 호스팅에 최적화된 배포 플랫폼이라는 말을 한다. 정적 웹 호스팅이란 무엇일까?
정적 웹사이트란 Static web site라고도 부르는데 "클라이언트가 서버에 페이지를 요청하면, 경로를 보고 거기에 맞는 HTML 파일을 찾아 클라이언트에게 파일을 돌려주는 방식",
즉 변경되지 않는 파일(html, css, js, 이미지 등)을 그대로 전달하는 방식의 웹사이트를 말한다. 서버에서 실시간 데이터 처리는 존재하지 않아 빠르다는 강점이 있습니다.
반면 동적 웹사이트는 Dynamic web site라고 부르며 "페이지의 틀만 만들어 두고 요청에 따라 서버가 처리한 내용을 다 채워넣고 그렇게 만들어진 HTML 파일을 제공하는 방식", 즉 유저의 요청에 따라 서버가 DB에서 실시간으로 데이터를 가져와 HTML을 생성해서 반환하는 방식의 웹사이트이다.
Bovo 프로젝트는 사용자가 도서를 선택하고 게시글을 작성하며, 실시간 채팅이 이루어지기 때문에 동적 웹사이트라고 생각했고, 그렇다면 Vercel, AWS S3, Netlify를 사용하지 못하는 것 아닌가라는 생각이 들었다. 허나 조사하다보니 오해하고 있는 부분도 있었고, 충분히 사용가능하다는 것을 알 수 있었다.
한 프로젝트 디렉토리 내에 서버와 화면 코드가 구성되어 있는 경우도 있지만, 화면은 ReactJS와 같은 SPA로 구성되어 있고, 서버는 spring으로 구성된 경우도 많이 볼 수 있다. 과거에는 동적 웹 페이지에 대해 서버에서 데이터를 가공해서 HTML까지 재구성하는 경우를 동적 웹페이지라고 불렀지만, 근래에는 앞서 말했듯 서버와 화면이 분리되어 잘 맞지 않는다는 글을 많이 볼 수 있었다.
현재의 경우에는 유저가 해당 url을 통해 웹페이지를 요청하면, 서버는 HTML 기본 골격만 전달해주고, 화면 구성을 ReactJS와 같은 것들이 구성해준다. 이때 동적인 변화가, 예를 들어 유저가 게시글을 생성해서 새글이 보인다던지와 같은 변화를 화면이 담당하는 것처럼 생각할 수 있다. 그러나 유저와 관련된 정보는 서버에서 데이터 가공을 해주면 화면은 데이터 통신(fetch, axios등) 함수를 통해 데이터를 받아오고, 이미 유저가 요청한 url 주소를 통해 다운받은 리소스(JS, CSS 등)에 의해 동작함으로써 코드 자체의 변화라기 보다는 Javascript의 동작에 의해 동적인 변화를 일으킨 것처럼 보인다. 이에 따라 화면은 정적 웹 호스팅에 최적화된 Vercel, AWS S3 등으로 배포하고, 서버는 동적인 변화를 위해 AWS EC2로 배포함으로써 정적 웹페이지의 장점과 동적 웹페이지의 장점을 모두 취할 수 있게 된다.
사실 배포하기 전 refactoring이나 이런 것들을 제외하고는 사전 준비랄 것까지야 생각나는 것은 없지만, bovo 프로젝트의 현재 구성상 bundlar 분석을 위해 rollup bundle analyzer 라이브러리를 설치했는데 이 명령어가 npm run build여서 일반적으로 사용하는 build 명령어와 동일하기에 명령어 충돌을 방지하고자 명령어 변경을 준비해야 했다.
우선 rollup bundle analyzer 설치시 설정했던 vite.config.js 파일을 수정해주어야 한다.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { visualizer } from 'rollup-plugin-visualizer';
// https://vite.dev/config/
export default defineConfig((configEnv) => {
const { mode } = configEnv;
const shouldAnalyze = mode === 'analyze';
return {
define: {
'global': 'window', // global을 window로 정의
},
plugins: [
react(),
...(shouldAnalyze
? [visualizer({
open: true,
filename: 'bundle-stats.html',
gzipSize: true,
brotliSize: true,
})]
: []),
],
}
})
=> plugins 부분이 rollup bundle analyzer 설정 관련 부분인데 shouldAnalyze라는 변수가 true일때 visualizer가 실행될 수 있도록 설정했다.
그 이후 package.json의 script 명령어를 설정해준다.
"scripts": {
"dev": "vite",
"build": "vite build",
"analyze": "vite build --mode analyze",
"lint": "eslint .",
"preview": "vite preview"
},
npm run analyze 명령어를 입력했을 때 mode가 analyze로 설정될 수 있도록 했으며 이에 따라 앞서 vite.config.js에서 설정한 shouldAnalyze의 조건문이 true로 되어 visualzer가 실행될 수 있도록 한 것이다.
우선 Netlify로 배포하기 위해서는 회원가입을 진행해야 한다.
해당 사이트(https://app.netlify.com/signup)에서 가입을 진행할 수 있다.

Github와 연동을 진행할 것이기에 Sign up with Github를 선택해준다.
이후 연동시킬 Github repo를 선택해주면 바로 다음과 같은 화면을 볼 수 있다.

이미 Github repository를 연결하였으므로 Add new project 버튼을 통해 현재 프로젝트를 사이트로 추가하겠다는 "Import an existing project" 버튼을 클릭해준다.

어떤 repo를 배포할 것인지 설정해야하는데 bovo 프로젝트의 경우에는 이미 회원가입시 초기설정으로 bookEvolution 팀을 추가했기에 목록에서 바로 선택할 수 있었다.

프로젝트를 추가하게 된다면 배포 관련 설정부분으로 넘어오게 된다.

※ project 이름 설정에 따라 사이트 경로의 이름이 달라지는 것으로 보인다.
이후 scroll을 아래로 내려가다 보면 build setting 관련 부분이 보인다.

하나씩 살펴보면
Branch to Deploy
배포할 repository의 branch를 선택하는 것으로 일반적으로 main branch를 많이 선택할 것이라 생각된다.
Base directory
만일 해당 branch 내에 server와 client 모두 구성했다면, 어느쪽의 directory 내 파일을 배포할 것인지 알려주어야 하는데, 현재 bovo project는 서버와 화면단 repository를 분리하여 진행하였지만, root directory가 bovo_client이기 때문에 bovo_client로 입력했다.

Build command
build 명령어를 입력하는 곳
과거에는 일반적인 build 명령어인 npm run build 명령어를 입력하면 완료되었으나 여러 블로그의 글과 Netlify 사이트를 살펴본 결과 CI 변수에 대해 입력해야 되는 것으로 파악됐다.
해당 사이트 : Netlify_support
2020년 6월 15일부로 build 명령시 build script 오류가 자주 발생함에 따라 추가된 옵션으로 보인다. 따라서 CI를 사용할 것이라면 CI=true npm run build or CI = npm run build로 입력해야 한다.
Publish directory
build 결과물이 생성되는 directory 경로를 입력해야 한다.
ReactJS와 같은 CRA는 build 결과물이 build라는 directory에 생성되며,
NextJS를 사용한다면 dist에 생성된다.
다만 bovo 프로젝트의 경우 VITE를 사용함으로써 dist 디렉토리에 build 생성물이 존재하기 때문에 dist로 설정해주어야 한다.
각 환경에 따라 달라지는 것으로 생각되며, 다시 한번 본인의 프로젝트 build 결과물이 어디서 생성될지 확인해야 할 것으로 보인다.
Functions directory
Serverless function을 정의하고 배포하는데 사용한다.
bovo 프로젝트의 경우 server가 존재하므로 설정할 필요가 없었다.
이제 좀 더 아래쪽으로 내려가면 환경변수를 설정하는 화면이 보인다.

환경 변수 추가 방법은 2가지로 Add key/value pairs로 환경변수의 key와 값인 value를 입력하는 방법과 Import from a .env file로 .env 파일을 업로드해서 적용하는 방법이 있다.
key/value로 업로드하게 되면 key, 즉 환경변수 입력하는 부분을 실제 사용하는 변수의 이름과 동일하게 설정해야 한다.
.env file을 업로드하는 방법은 배포 이후 로컬에서 .env 파일을 수정한다고 해서 배포된 사이트에 적용되지 않는다는 점을 주의해야 한다.
이후 완료가 되었다면 Deploy 버튼을 클릭한다.
Deploy 버튼을 클릭하게 되면 다음과 같은 배포 과정이 진행된다.

모든 과정이 정상적으로 통과되어야지 배포를 성공할 수 있다.
build하기 전 다시 한번 import 경로를 확인해보자
(본인은 대소문자를 바꿔 경로를 입력하여 build에 여러번 실패했다.)
또한 주의사항으로써 .env, 즉 환경변수를 나중에 추가할 수도 있는데 이럴 때는

[Deploy]-[Trigger deploy]-[Deploy project]를 선택하여 재배포를 진행해주어야 추가된 환경변수가 적용된다.
글이 너무 길어지는 관계로 다음 글에서 AWS S3로 배포하는 방법에 대해 기술하고자 한다.