avatar
Octoping Blog

NestJS 서버를 서버리스로 Vercel에 배포하기

NestJS를 서버리스로 배포해서 무료로 사용해봅시다
ServerlessNestJS
Nov 5
·
6 min read

들어가기 전에

Nest.js는 Node.js 진영에서 널리 쓰이고 있는 서버 프레임워크이다.

그리고 이런 서버를 클라우드 환경에 배포하기 위해서는 AWS EC2, Oracle Cloud 등의 컴퓨팅 인스턴스 위에 올리는 방법이 정석이겠다.

 

하지만 Nest.js는 서버리스를 지원하고, Vercel은 서버리스를 지원한다.
이를 이용해서 무료로 간단히 Vercel에 서버를 배포할 수 있다.

방법

방법 자체는 간단하다. 프로젝트 최상단에 vercel.json을 만들고 다음과 같이 작성한다.

{
  "version": 2,
  "builds": [
    {
      "src": "src/main.ts",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "src/main.ts",
      "methods": [
        "GET",
        "POST",
        "PUT",
        "DELETE"
      ]
    }
  ]
}

그 후 npm install -g vercel 을 실행한 후, 프로젝트 최상단 경로에서 vercel .를 실행하면 완성된다.

트러블 슈팅

Cannot find module

1972

배포를 했지만 다음과 같은 오류가 떠서 처음에 큰 고생을 했다.

Vercel에서 로그를 확인해보니 아래와 같은 에러 로그가 있었다.

2023-08-18T17:52:14.322Z	undefined	ERROR	Cannot find module 'src/infra/prisma/PrismaService'
Require stack:
- /var/task/src/feed/feed.module.js
- /var/task/src/app.module.js
- /var/task/src/main.js
2023-08-18T17:52:14.323Z	undefined	ERROR	Did you forget to add it to "dependencies" in `package.json`?
RequestId: 059dec36-4319-4851-9c23-3ecf01978f18 Error: Runtime exited with error: exit status 1
Runtime.ExitError
1974

분명 잘 존재하는 모듈을 발견하지 못하고 있다고 에러가 떴다.

왜;;인지 도저히 알기가 어려워 많이 헤맸는데, 문제는 내 import 문에 있었다.

import { PrismaService } from '@/infra/prisma/PrismaService';

다음과 같이 path alias를 사용해서 절대 경로로 import 하는 경우 Vercel이 경로를 인식을 못하는 이슈였다.

src/infra/prisma/PrismaService 처럼 @를 안 쓰고 절대경로로 쓰더라도 마찬가지였다. 상대경로로 작성해야 한다!

Swagger 페이지 404 에러 (검증 못 해봄)

다른 페이지는 잘 나오지만 Swagger 페이지만 아무것도 안 나오는 이슈 (404 에러)가 발생한다.

Uncaught ReferenceError: SwaggerUIBundle is not defined
    at window.onload

개발자 도구를 켜보면 이런 로그가 나온다.

C# 쪽 스웨거에서도 한번 제보된 문제이긴 하다. swagger ui 파일이 서버리스에 올라가기에는 너무 크다는 이슈다.

swagger-ui-bundle.js too large for AWS Lambda and ALB
Updated to .NET Core 3.1 and the latest version of Swashbuckle but found the swagger UI wasn't working correctly. The swagger-ui-bundle.js was failing to load with a 502. Tracked this down to a A...
https://stackoverflow.com/questions/63363123/swagger-ui-bundle-js-too-large-for-aws-lambda-and-alb

따로 CDN에 swagger js나 css를 올려놓고, 서버리스에 올리는 대신 받아오는 방식으로 사용해볼 수 있겠다는 생각인데.

const CSS_URL = "cdnjs.cloudflare.com/ajax/libs/swagger-ui/4.1.0/swagger-ui.min.css";
swaggerUI.setup(specs, { customCssUrl: CSS_URL })

이런 방식으로 사용해볼 수 있다는 듯 하다.

When deploying swagger on vercel on nodejs it does not show UI · Issue #8461 · swagger-api/swagger-ui
This is How it does look like this and I do not know how to fix this issue. Q&A (please complete the following information) OS: M1 Pro Browser" Chrome, Safari Version: 22 Method of installation: np...
https://github.com/swagger-api/swagger-ui/issues/8461#issuecomment-1497927943

TMI

실제로 until을 처음 개발할 당시에 서버비를 줄이기 위해 다음 방법으로 한동안 개발했었다..

지금은 AWS + Kotlin Spring으로 넘어갔지만, 그래도 당시에 고려했던 점들을 몇 가지 적어본다.

  1. NestJS의 경우 서버 실행 초기에 bootstrap하는 과정을 거치는데, 이걸 api가 들어올 때마다 해야한다면 꽤 무거운 작업일 수밖에?

  2. 서버리스로 구성할 경우 api가 들어올 때마다 함수가 실행되는 꼴이므로, 트래픽이 몰리는 경우 DB의 커넥션 풀을 굉장히 잡아먹을 가능성이 높다. 이는 서버리스의 고질적 문제이긴 하다.

    • 프로젝트의 persistence 라이브러리로 채택한 Prisma의 경우 이런 문제를 해결해준다고 공식 사이트에 적혀는 있다. 하지만 좀 걱정된다

      1976



- 컬렉션 아티클






반갑습니다 😄