Sevalla에 Next.js 배포하기은(는) 무엇을 하나요?
Sevalla는 Next.js를 위한 두 가지 호스팅 제품을 제공하는 PaaS(Kinsta 제공)입니다:
- Application Hosting은 실제 Node.js 서버를 실행합니다. SSR, 라우트 핸들러(API 라우트), 프록시(이전 미들웨어), ISR(
revalidate), 서버 액션 또는 웹소켓에 필요합니다. - Static Site Hosting은 정적 내보내기(
output: 'export')의 출력물을 제공합니다. 서버 측 코드가 전혀 없습니다. 회사당 최대 100개의 정적 사이트로 제한됩니다.
먼저 이 결정을 올바르게 내리세요. 이는 아래 모든 내용을 결정합니다.
0단계: 사용할 호스팅 제품 결정
다른 작업을 수행하기 전에 리포지토리를 검사하세요:
next.config.js/next.config.ts/next.config.mjs에서output: 'export'또는output: 'standalone'을 확인합니다.- 코드베이스에서 다음을 검색합니다:
app/api/,pages/api/,proxy.ts또는proxy.js(Next.js 16),middleware.ts또는middleware.js(Next.js 15 이하),"use server",getServerSideProps,revalidate(ISR),NextResponse, 또는 서버 측에서 사용되는 데이터베이스 또는 인증 클라이언트. - 결정:
- 위 항목 중 하나라도 있으면: Application Hosting (서버 필요). 1단계로 이동합니다.
- 없고, 완전히 정적 콘텐츠, 마케팅 또는 블로그인 경우: Static Site Hosting이 더 간단하고 저렴합니다.
references/static-hosting.md를 읽으세요. - 확실하지 않거나, 사용자가 나중에 동적 기능을 원하는 경우: 기본적으로 Application Hosting을 선택합니다. 정적 호스팅이 할 수 있는 모든 것을 할 수 있습니다.
진정으로 모호한 경우 사용자에게 "이 앱에 라이브 서버(API 라우트, ISR, 인증, 데이터베이스 호출)가 필요한가요, 아니면 완전히 정적인 콘텐츠인가요?"라는 질문을 하나만 하세요. 조용히 추측하지 마세요. 잘못된 선택은 전체 배포를 다시 해야 하기 때문입니다.
또한 데이터베이스 클라이언트(Prisma, Drizzle, pg, mysql2, Mongoose, redis, ioredis)와 파일 업로드가 있는지 리포지토리를 확인하세요. 찾으면 3단계 전에 references/data-services.md를 읽으세요.
1단계: 빌드 전략 선택 (Application Hosting)
Sevalla는 네 가지 전략 중 하나로 Git 기반 애플리케이션을 빌드합니다:
- Nixpacks, 기본값. 표준 Next.js 앱의 경우 설정이 필요 없습니다. 이유가 없는 한 사용하세요.
- Railpack, Nixpacks의 후속 제품. 또한 설정이 필요 없습니다. 새 앱에 좋은 선택입니다. API 필드
build_type: "railpack"으로 설정하세요. - Dockerfile, 사용자가 작고 재현 가능한 이미지를 원하거나, 자동 감지 빌더가 어려워하는 모노레포가 있거나, Docker를 요청하는 경우.
- Buildpacks (
pack). Next.js에는 거의 필요하지 않습니다.
구성을 작성하기 전에 references/app-hosting.md를 읽으세요. 정확한 package.json 스크립트, 권장 Dockerfile, nixpacks.toml 오버라이드 및 모노레포 빌드 경로 설정이 있습니다. 일반적인 Next.js 지식으로 Dockerfile 또는 nixpacks.toml을 직접 작성하지 마세요. Sevalla에는 일반 가이드에서 언급하지 않는 특정 제약 조건(아래 참조)이 있습니다.
2단계: 리포지토리 준비 (Sevalla 제약 조건)
다음은 거의 모든 첫 배포에서 문제를 일으킵니다. 배포하기 전에 모두 확인하세요:
$PORT에서 포트를 읽고0.0.0.0에 바인딩하세요. 기본 웹 프로세스 포트는 8080이며, Sevalla는 이를PORT로 전달합니다. 인터넷에는 포트 80과 443만 열려 있으며, Sevalla는 이를$PORT로 라우팅합니다. Nixpacks 또는 Railpack을 사용하는 경우 시작 스크립트는next start -p ${PORT:-8080} -H 0.0.0.0이어야 합니다. 일반next start는 3000에서 수신 대기합니다.NEXT_PUBLIC_*변수는 빌드 시 인라인됩니다. 빌드가 실행되기 전에 빌드 시간 변수(is_buildtime: true)로 생성하세요. 나중에 추가된 변수는 재시작이 아닌 새 배포가 필요합니다.- 파일 시스템은 일시적입니다. 앱이 런타임에 디스크에 쓰는 모든 것(업로드, 생성된 파일, 디스크 캐시)은 재배포 또는 재시작 시 손실됩니다. 객체 스토리지를 사용하거나, 앱이 로컬 디스크 쓰기를 정말로 필요로 하는 경우(예: SQLite 또는 자체 호스팅 CMS) 퍼시스턴트 디스크를 사용하세요.
references/data-services.md를 참조하세요. output: 'standalone'은 Dockerfile에서만 사용하세요.next start는 독립형 번들을 사용하지 않으며, Next.js는"next start" does not work with "output: standalone" configuration이라고 경고합니다. 따라서 Nixpacks 또는 Railpack을 사용하는 경우output을 설정하지 않은 상태로 두세요. Dockerfile을 사용하는 경우output: 'standalone'을 설정하세요.node_modules또는.next를 커밋하지 마세요. 커밋된node_modules폴더는 Sevalla에서 빌드 실패의 문서화된 원인입니다.- Node.js 버전을 고정하세요. Nixpacks는 기본적으로 Node 18을 사용하며, Next.js 16은 Node 20.9 이상이 필요합니다.
package.json에"engines": { "node": "22.x" }를 설정하거나 빌드 시간 변수NIXPACKS_NODE_VERSION=22를 설정하세요. - 모노레포: 빌드 경로(API 필드
build_path)를 Next.js 앱의 폴더(예:apps/web)로 설정하세요. Dockerfile을 사용하는 경우docker_context및dockerfile_path도 설정하세요. package.json이름: 패키지 이름으로"node"또는"js"를 사용하지 마세요. Sevalla 빌드를 중단시키는 것으로 문서화되어 있습니다.- 변수 값의 큰따옴표는
"로 이스케이프해야 합니다. 이스케이프되지 않은 따옴표는 삭제되거나 롤아웃을 실패하게 만듭니다. - 비밀(데이터베이스 URL, API 키)은 Sevalla 환경 변수에 저장하세요. 실제 비밀이 있는
.env파일을 절대 커밋하지 마세요.
3단계: 배포
사용 가능한 첫 번째 옵션을 다음 순서로 사용하세요:
- Sevalla MCP 서버 (
https://mcp.sevalla.com/mcp). 두 가지 도구가 있습니다:search는 사양에서 API 엔드포인트를 찾고,execute는sevalla.request({ method, path, body })를 호출하는 JavaScript를 실행합니다. 아래 표의 API 경로를 사용하세요. sevallaCLI, 모든 명령에--json을 사용하여 ID를 읽을 수 있도록 합니다.npm install -g @sevalla/cli(Node 22+) 또는brew install sevalla-hosting/tap/sevalla로 설치하세요.sevalla login으로 로그인하거나SEVALLA_API_TOKEN을 설정하세요.- REST API,
https://api.sevalla.com/v3에서 Bearer API 키와 함께 사용합니다.
아무것도 사용할 수 없는 경우, 사용자에게 MCP 서버를 추가하는 방법을 알려주거나(https://docs.sevalla.com/quick-starts/coding-agents/overview 참조), references/dashboard.md의 대시보드 단계를 알려주세요. 처음 로그인만 사용자가 필요합니다.
Application Hosting
| # | 작업 | API (MCP execute 또는 REST) | CLI |
|---|---|---|---|
| 1 | 위치 선택 | GET /resources/clusters | sevalla resources clusters --json |
| 2 | 앱 생성 | POST /applications with display_name, cluster_id, source (privateGit for a connected GitHub, GitLab or Bitbucket repo, publicGit for a public URL), git_type, repo_url, default_branch | sevalla apps create --name <name> --cluster <cluster-id> --source privateGit --git-type github --repository https://github.com/<owner>/<repo> --branch <branch> --json |
| 3 | 기본값이 아닌 경우 빌드 전략 및 빌드 경로 설정 | PATCH /applications/{id} with build_type (nixpacks, railpack, dockerfile, pack) and build_path | sevalla apps update <app-id> --build-type railpack --json. CLI에는 빌드 경로 플래그가 없습니다: sevalla apps update <app-id> --data '{"build_path":"apps/web"}' --json |
| 4 | 환경 변수 추가 | POST /applications/{id}/env-vars with key and value. is_runtime and is_buildtime both default to true, which is right for NEXT_PUBLIC_*. | sevalla apps env-vars create <app-id> --key <KEY> --value "<value>" (빌드 시간 및 런타임에 사용 가능) |
| 5 | 데이터베이스 연결(있는 경우) | references/data-services.md 참조 | |
| 6 | 배포 | POST /applications/{id}/deployments. 앱 생성은 배포를 시작하지 않습니다. | sevalla apps deployments trigger <app-id> --branch <branch> --json |
2단계가 privateGit 리포지토리에서 HTTP 500으로 실패하는 경우, 가장 가능성 있는 원인은 Sevalla의 GitHub 앱이 리포지토리를 볼 수 없는 것입니다. API가 이를 알려주지 않습니다. sevalla git providers --json으로 확인하세요: settings_url은 GitHub 앱 설치를 엽니다. 사용자(또는 GitHub 조직 소유자)는 앱에 리포지토리에 대한 액세스 권한을 부여해야 합니다. 사용자가 소유하지 않은 조직의 리포지토리는 소유자가 추가해야 합니다. 그런 다음 2단계를 다시 시도하세요.
새 앱은 자동 배포가 꺼져 있습니다. 사용자가 푸시할 때마다 배포를 원하는 경우 PATCH /applications/{id}로 auto_deploy: true를 설정하세요(privateGit에서만 작동).
Static Site Hosting의 경우 대신 references/static-hosting.md를 따르세요. 정적 사이트를 생성하면 첫 번째 배포가 자동으로 시작됩니다.
4단계: 확인
시작된 배포가 제대로 작동하는 배포는 아닙니다. 완료되었다고 사용자에게 알리기 전에 다음을 모두 수행하세요:
- 빌드를 기다리세요. 15~30초마다
GET /applications/{id}/deployments/{deployment_id}(CLI:sevalla apps deployments get <deployment-id> --app-id <app-id> --json)를 폴링하여status가success또는failed가 될 때까지 기다립니다. 다른 값은waiting,inProgress,cancelled및skipped입니다. - 실패한 경우 빌드 로그를 읽으세요.
GET /applications/{id}/deployments/{deployment_id}/logs(CLI:sevalla apps deployments logs ...). 오류를references/app-hosting.md의 문제 해결 표와 대조하고, 원인을 수정한 후 다시 배포하세요. 로그를 읽지 않고 두 번 추측하지 마세요. 성공 여부는 로그 심각도가 아닌 배포status로 판단하세요: 정상적인 빌드 출력물이 stderr로 기록되면 성공적인 빌드에서도"severity": "error"로 나타납니다. - 라이브 URL을 찾으세요.
GET /applications/{id}/domains(CLI:sevalla apps domains list --app-id <app-id> --json). 모든 앱은 첫 번째 성공적인 배포 후 무료*.sevalla.app도메인을 받습니다. - URL을 요청하세요.
/와 (앱에 있는 경우) 하나의 라우트 핸들러에서 HTTP 200을 예상합니다. 502 또는 시간 초과는 일반적으로 서버가$PORT및0.0.0.0에서 수신 대기하지 않음을 의미합니다. - 앱이 오류로 응답하는 경우 런타임 로그를 읽으세요.
GET /applications/{id}/runtime-logs(CLI:sevalla apps logs runtime <app-id>).
그런 다음 사용자에게 라이브 URL, 구성한 내용, 그리고 사용자가 직접 수행해야 하는 작업(예: 사용자 정의 도메인에 대한 DNS 레코드 추가)을 알려주세요.
5단계: 선택적 다음 단계
- 사용자 정의 도메인:
sevalla apps domains add <app-id> --name example.com. 사용자는 Sevalla가 반환하는 DNS 레코드를 추가해야 합니다. SSL이 포함됩니다. - 스케일링:
sevalla apps processes update <process-id> --app-id <app-id> --instances <n>. 인스턴스가 두 개 이상인 경우 공유 상태에 퍼시스턴트 디스크를 사용하지 마세요. 객체 스토리지 또는 데이터베이스를 사용하세요. - 롤백:
sevalla apps deployments rollback <app-id> --deployment-id <id>.
참조 파일
references/app-hosting.md:package.json스크립트, Nixpacks 및 Railpack 참고 사항, 권장 Dockerfile, 모노레포 설정, 문제 해결 표.references/static-hosting.md: Static Site Hosting을 위한 정적 내보내기 설정 및 배포.references/data-services.md: 데이터베이스, 객체 스토리지 및 퍼시스턴트 디스크, 그리고 해당 연결 세부 정보가 앱에 도달하는 방법.references/dashboard.md: 사용자를 위한 Sevalla 대시보드의 동일한 단계.