Next.js 운영 배포 전략

이효범·2024년 8월 11일
1

React

목록 보기
6/6

정확히 어떻게 하는건데 ?

이번에 아하철 프로젝트를 드디어 운영 단계로 배포해야해서
챗지피티랑 대화해본 내용을 기록해요.

질문:

vite의 경우 장점이 매우 빠른 개발 서버와 빌드 속도라고 하자나,
근데 여기서 궁금한게 개발 서버라는 것이 무엇을 의미하느냐는것이야.
예를 들어서 next.js를 사용한다고할때
local에서 실행할때 next.js도 next.js만의 개발 서버가 존재하겠지?
근데 이 프로젝트를 실제로 프로덕션에 배포한다고 쳐,
그리고 aws를 이용한다고 쳐,
그럼 이때 next.js같은 경우는 node가 원활하게 돌아갈 수 있게끔
프로덕션에서 돌아가는 서버를 따로 구축을 해야하는걸로 알고있는데
이와 달리 cra나 vite는 빌드 후 생성된 정적인 index.html인가 하나만 cloudFront같은 곳에 올려서 배포할 수 있는 걸로 알고있는데
이에 대해서 자세히 설명해줄수있어?
즉, next.js라는 특별한 프레임워크를 실제 프로덕션에 배포할때와 그외의 CRA, vite등의 차이점에 대해 자세히게 설명해줘.

대답:

개발 서버와 프로덕션 배포는 프론트엔드 개발에서 중요한 개념입니다. 여기서 Vite, CRA (Create React App), Next.js와 같은 도구들의 차이점을 이해하는 것이 중요합니다.

1. 개발 서버란 무엇인가?

개발 서버는 로컬 환경에서 애플리케이션을 실행하고 개발하는 동안 개발자가 즉시 변경 사항을 확인할 수 있게 도와주는 서버입니다. 개발 서버는 다음과 같은 기능을 제공합니다:

  • 자동 리로딩: 코드가 변경될 때마다 브라우저가 자동으로 새로고침되어 최신 상태를 반영합니다.
  • 빠른 피드백: 변경 사항이 즉각적으로 반영되기 때문에 개발자가 빠르게 피드백을 받을 수 있습니다.
  • 모듈 핫 리플레이스먼트(HMR): 전체 페이지를 새로고침하지 않고도 변경된 모듈만을 교체하여 빠르게 반영합니다.

Vite와 CRA는 모두 이러한 개발 서버를 제공하여 개발 중에 빠른 피드백을 가능하게 합니다. Next.js도 자체 개발 서버를 제공하여, next dev 명령어로 로컬 환경에서 서버를 실행할 수 있습니다.

2. 프로덕션 배포: CRA/Vite vs. Next.js

프로덕션 배포는 로컬 개발과는 다르게 애플리케이션을 실제 사용자가 접근할 수 있도록 하는 과정입니다. 이 과정에서 도구와 프레임워크마다 차이가 있습니다.

CRA/Vite의 프로덕션 배포

CRA와 Vite는 주로 정적인 웹 애플리케이션을 만드는 도구입니다. 이 경우:

  • 빌드 과정: 애플리케이션을 프로덕션 모드로 빌드하면, index.html, CSS, JavaScript 파일 등이 생성됩니다. 이들은 모두 정적인 파일입니다.
  • 배포: 이 정적인 파일들을 웹 서버(예: Nginx)나 클라우드 제공 서비스(예: AWS S3, CloudFront)에 업로드합니다. 여기서 중요한 점은 이 파일들이 정적이라는 것입니다. 즉, 서버 측에서 추가적인 계산이나 서버 로직이 필요하지 않습니다.
  • 서버: 실제로는 정적 파일을 제공하는 역할만 하기 때문에 별도의 Node.js 서버가 필요하지 않습니다. 웹 서버나 CDN을 통해 빠르게 파일을 서빙할 수 있습니다.

Next.js의 프로덕션 배포

Next.js는 정적 사이트 생성(SSG)과 서버 사이드 렌더링(SSR)을 모두 지원하는 프레임워크입니다. 이 두 가지 기능은 프로덕션 배포에서 큰 차이를 만듭니다.

  • SSG: 빌드 시점에 HTML 파일을 생성하며, 이 파일들은 CRA/Vite와 마찬가지로 정적 파일로 배포될 수 있습니다. 정적 파일로만 구성된 페이지는 AWS S3와 CloudFront 같은 곳에 배포할 수 있습니다.
  • SSR: 특정 페이지는 사용자가 요청할 때마다 서버에서 동적으로 생성됩니다. 이 경우, Next.js 서버가 Node.js 환경에서 실행되어야 하며, 요청에 따라 HTML을 생성하여 반환합니다.
  • 배포: Next.js를 SSR로 사용할 경우, Node.js 서버가 필요하며, 이를 위해 AWS EC2와 같은 인스턴스를 사용하여 서버를 직접 운영하거나, Vercel과 같은 플랫폼을 사용할 수 있습니다. Vercel은 Next.js의 제작사이기도 하며, 이 플랫폼을 통해 SSR, SSG 모두 쉽게 배포할 수 있습니다.

3. 정리

  • CRA/Vite: 주로 정적 사이트를 생성하며, 빌드 후 생성된 정적 파일을 웹 서버나 CDN에 배포합니다. 서버 측 로직이 필요 없으며, Node.js 서버가 필요하지 않습니다.
  • Next.js: SSR 및 SSG 모두를 지원하는 유연한 프레임워크입니다. SSG로만 사용할 경우 정적 파일로 배포할 수 있지만, SSR 기능을 사용하려면 Node.js 서버가 필요합니다. Next.js는 이러한 동적 서버 구성 및 서버 렌더링 기능이 필요할 때, 별도의 서버를 운영해야 합니다.

이러한 차이로 인해 CRA/Vite와 Next.js는 배포 전략과 요구 사항이 다릅니다. 간단히 말해서, CRA/Vite는 정적 사이트 배포에 적합하고, Next.js는 동적 서버 렌더링이나 복잡한 기능을 필요로 할 때 적합합니다.

질문

그럼 next.js의 적절한 배포전략에 대해서말해줘. aws ec2를 이용하려고 했었어.
그리고 vercel의 무료버전을 이용해서 배포하면 ssr을 사용하는 페이지의 초기로딩속도가
초기 진입시에는 꽤나 느린데 이 이유는 무엇인지 알아?
무료버전이라서 node가 돌아가는 서버의 성능이 좋지 않은거야?

대답

Next.js의 적절한 배포 전략 (AWS EC2 기반)

Next.js 애플리케이션을 AWS EC2에 배포하려는 경우, 다음과 같은 절차와 전략을 따를 수 있습니다:

  1. EC2 인스턴스 선택:

    • 인스턴스 타입: 서버 사이드 렌더링(SSR)을 위해서는 Node.js가 실행될 수 있는 EC2 인스턴스가 필요합니다. 웹 트래픽과 애플리케이션의 복잡성에 따라 t3.medium 또는 t3.large와 같은 인스턴스 타입을 선택할 수 있습니다.
    • OS 선택: Ubuntu, Amazon Linux 등 익숙한 리눅스 배포판을 선택합니다.
  2. Node.js 환경 설정:

    • Node.js 설치: EC2 인스턴스에 Node.js와 NPM을 설치합니다.
    • Next.js 애플리케이션 배포: 소스 코드를 EC2 인스턴스로 전송하고, npm install을 통해 필요한 패키지를 설치합니다.
    • 빌드 및 실행: npm run build를 통해 프로덕션 빌드를 만들고, npm start 또는 PM2와 같은 프로세스 매니저를 사용해 애플리케이션을 실행합니다.
  3. Reverse Proxy 설정:

    • Nginx: Nginx를 설치하고, Reverse Proxy로 설정하여 80번 포트로 오는 요청을 Node.js 애플리케이션으로 전달합니다. 이를 통해 SSL 설정이나 도메인 관리도 가능해집니다.
  4. 자동 배포 및 확장:

    • CI/CD: AWS CodePipeline, GitHub Actions 또는 Jenkins를 사용하여 CI/CD 파이프라인을 구축합니다.
    • 로드 밸런싱 및 확장: 트래픽이 증가하면 EC2 인스턴스를 추가하고, AWS Elastic Load Balancer(ELB)를 통해 로드 밸런싱을 설정할 수 있습니다.

Vercel 무료 버전에서 초기 로딩 속도가 느린 이유

Vercel은 Next.js 애플리케이션 배포에 최적화된 플랫폼이며, 무료 플랜을 제공하지만, SSR 페이지의 초기 로딩 속도가 느릴 수 있습니다. 그 이유는 다음과 같습니다:

  1. Cold Start:

    • 무료 플랜에서는 애플리케이션이 유휴 상태로 일정 시간 동안 요청을 받지 않으면 서버가 종료(cold)될 수 있습니다. 이때 새 요청이 들어오면 서버가 다시 시작되는데, 이 과정에서 초기 로딩이 느려질 수 있습니다. 이 현상은 "콜드 스타트(cold start)"라고 부르며, 이로 인해 초기 진입 시 성능 저하가 발생할 수 있습니다.
  2. 서버 리소스 제한:

    • 무료 플랜에서는 서버 리소스(CPU, 메모리 등)에 제한이 있을 수 있습니다. 이는 동일한 트래픽에서 유료 플랜보다 성능이 떨어질 수 있음을 의미합니다. 특히, Node.js와 같이 서버 자원을 많이 사용하는 SSR의 경우, 이러한 리소스 제한이 초기 로딩 시간에 영향을 미칠 수 있습니다.
  3. 네트워크 대기 시간:

    • Vercel의 무료 플랜은 기본적으로 글로벌 CDN을 통해 정적 콘텐츠를 빠르게 제공하지만, SSR은 원격 서버에서 실행됩니다. 이 경우, 서버의 지리적 위치와 사용자의 위치 간의 네트워크 대기 시간이 초기 로딩에 영향을 줄 수 있습니다.

결론

  • EC2 기반 배포: 안정적인 서버 성능과 자유로운 확장성을 원한다면, EC2에 직접 배포하는 것이 좋은 선택입니다. 이를 통해 서버 사양을 자유롭게 조정하고, 로드 밸런싱 및 자동 확장 설정도 가능합니다.
  • Vercel 무료 플랜: 초기 로딩 속도가 느린 이유는 주로 콜드 스타트와 서버 리소스 제한 때문입니다. 이러한 문제를 해결하기 위해서는 유료 플랜을 고려하거나, EC2와 같은 독립된 인프라를 사용하는 것이 좋습니다. 유료 플랜에서는 콜드 스타트 문제가 완화되며, 더 많은 리소스를 사용할 수 있기 때문에 성능이 향상될 수 있습니다.

질문

응 next.js를 AWS EC2에 배포하는 전략을 사용한다고 치고,
여기에 추가적으로 젠킨스나 Docker을 함께 적용하는 전략은 어떠니?
장점에 대해 알려줘

대답

Next.js를 AWS EC2에 배포하는 과정에 Jenkins와 Docker를 함께 사용하는 전략은 매우 강력한 배포 파이프라인을 구축할 수 있습니다. 이 조합을 사용하면 여러 가지 장점이 있습니다.

1. Docker를 사용하는 장점

  • 일관된 환경 제공: Docker를 사용하면 로컬 개발 환경과 프로덕션 환경 간의 차이로 인한 문제를 최소화할 수 있습니다. 애플리케이션이 컨테이너 안에서 실행되기 때문에, 어디서든 동일한 환경에서 동작하게 됩니다.
  • 배포의 단순화: Docker 이미지를 사용하면 애플리케이션, 종속성, 환경 설정 등을 모두 하나의 패키지로 묶어 배포할 수 있습니다. 이는 배포 과정을 단순화하고, "빌드 한 번, 어디서든 실행"할 수 있게 해줍니다.
  • 확장성: Docker를 사용하면 EC2 인스턴스 내에서 여러 컨테이너를 손쉽게 실행할 수 있으며, 필요에 따라 컨테이너 수를 조절할 수 있어 확장성이 뛰어납니다.
  • 롤백의 용이성: 문제가 발생할 경우 이전 버전의 Docker 이미지를 간단히 다시 실행하여 롤백할 수 있습니다.

2. Jenkins를 사용하는 장점

  • 자동화된 CI/CD 파이프라인: Jenkins는 코드의 변경 사항이 있을 때마다 자동으로 빌드, 테스트, 배포 과정을 실행할 수 있습니다. 이를 통해 배포 주기를 단축하고, 수동 작업을 줄여 개발 효율성을 높일 수 있습니다.
  • 통합 테스트 및 품질 관리: Jenkins 파이프라인에 통합 테스트와 코드 품질 검사를 추가하여, 배포 전에 코드의 안정성을 확보할 수 있습니다. 이는 프로덕션 환경에서의 문제를 미리 방지할 수 있는 강력한 도구가 됩니다.
  • 버전 관리 및 기록: Jenkins를 통해 빌드 및 배포 내역을 기록할 수 있으며, 언제든지 이전 상태로 돌아갈 수 있습니다. 이를 통해 배포의 가시성과 관리성을 높일 수 있습니다.
  • 확장성: Jenkins는 플러그인 기반으로 동작하기 때문에, 다양한 툴과 통합이 가능합니다. 예를 들어, AWS와의 통합, Docker와의 통합 등을 쉽게 설정할 수 있습니다.

3. Docker와 Jenkins를 함께 사용하는 경우의 시너지

  • 일관된 빌드와 배포: Jenkins에서 Docker 이미지를 빌드하고, 이 이미지를 EC2에 배포하는 파이프라인을 구축하면, 일관된 빌드와 배포를 보장할 수 있습니다. Jenkins에서 Docker 이미지를 빌드하고, 성공적으로 빌드된 이미지를 EC2 인스턴스에 배포하는 자동화된 프로세스를 구성할 수 있습니다.
  • 배포 속도 향상: Docker 이미지 빌드는 비교적 빠르게 이루어지며, Jenkins에서 이를 자동화하면 배포 속도가 크게 향상됩니다. 특히, 빌드한 이미지를 Docker Hub나 ECR(AWS Elastic Container Registry)에 푸시하고, 이를 EC2에서 바로 가져와 실행할 수 있습니다.
  • 테스트 자동화: Docker 컨테이너 내부에서 테스트를 실행하고, Jenkins가 이를 관리하게 하면, 배포 전 테스트 환경을 더 쉽게 재현하고 관리할 수 있습니다. 이를 통해 코드 변경 사항이 실제 환경에서 어떻게 동작할지 미리 확인할 수 있습니다.

4. 실제 구현 전략 예시

  1. Dockerfile 작성: Next.js 애플리케이션을 위한 Dockerfile을 작성하여, 애플리케이션과 필요한 종속성을 포함한 이미지를 정의합니다.

  2. Jenkins 파이프라인 설정:

    • 코드 변경 감지: GitHub 등의 리포지토리에 코드 변경이 있을 때 Jenkins가 이를 감지하도록 설정합니다.
    • Docker 빌드: 코드 변경이 감지되면 Jenkins가 Docker 이미지를 빌드하고, 테스트를 실행합니다.
    • 이미지 푸시: 성공적으로 빌드된 Docker 이미지를 Docker Hub나 AWS ECR에 푸시합니다.
    • 배포: Jenkins가 EC2 인스턴스에 SSH로 접속하여, 최신 이미지를 pull하고 컨테이너를 재시작합니다.
  3. EC2에서 Docker 실행: EC2 인스턴스에서 Jenkins가 푸시한 Docker 이미지를 pull하고, 컨테이너로 실행합니다. 필요 시 Nginx나 Load Balancer를 사용하여 트래픽을 관리합니다.

5. 결론

Docker와 Jenkins를 활용하면 Next.js 애플리케이션의 배포를 보다 안정적이고 자동화된 방식으로 관리할 수 있습니다. Docker는 환경의 일관성을 보장하고, Jenkins는 이 모든 과정을 자동화하여 효율적인 CI/CD 파이프라인을 구축할 수 있습니다. 이 전략은 특히 팀 규모가 커지거나 배포 빈도가 높은 프로젝트에서 매우 유용합니다.

profile
I'm on Wave, I'm on the Vibe.

0개의 댓글