it ·

Node.js 가비아 호스팅 배포 시 발생하는 흔한 오류와 해결법

반응형
Node.js 서버 배포와 장애 대응
Node.js 배포 환경에서는 “설정 1줄” 때문에 502/403이 자주 발생합니다. (체크리스트로 빠르게 복구하세요)

Node.js 가비아 호스팅 배포 시 발생하는 흔한 오류와 해결법

가비아(Node.js/컨테이너/웹호스팅 포함) 환경에 Node.js 프로젝트를 올릴 때, 에러의 대부분은 “코드”보다 실행 방식(PM2), 엔트리 파일, 포트/프록시, 권한, 빌드 산출물에서 터집니다. 이 글은 검색해서 흩어진 힌트를 모으는 대신, 배포 직후 가장 자주 만나는 에러를 증상 → 원인 → 즉시 해결 → 재발 방지 순서로 정리한 실전 가이드입니다.

📌 이미지 삽입 위치 #1 (예: “가비아 콘솔에서 SSH/SFTP 설정 화면” 스크린샷)

0) 배포 장애를 3분 안에 줄이는 “초기 체크리스트”

가장 먼저 확인할 7가지

  1. 엔트리 파일: 서버 실행 파일이 index.js / server.js / app.js 중 무엇인지 확정
  2. 실행 명령: npm start가 실제로 서버를 띄우는지(스크립트가 비어있거나 다른 명령이면 실패)
  3. 포트 바인딩: 앱이 process.env.PORT를 사용하도록 되어 있는지
  4. 프로세스 유지: SSH에서 node index.js로만 띄우면 세션 종료 시 꺼짐 → PM2 권장
  5. 의존성 설치: 서버에서 npm ci 또는 npm install이 정상 종료되는지
  6. 빌드 산출물: Next/Nuxt/React SSR 계열은 npm run build 결과물이 실제로 존재하는지
  7. 로그: “에러가 났다”가 아니라 로그에 찍힌 첫 에러를 확보했는지

가장 자주 쓰는 명령(로그/상태 확인)

node -v
npm -v

# PM2 사용 시
pm2 list
pm2 show myapp
pm2 logs myapp --lines 200
pm2 restart myapp

📌 이미지 삽입 위치 #2 (예: “pm2 list / pm2 logs 캡처”)

1) 403 Forbidden (권한/인덱스 파일/실행 권한 문제)

증상

  • 접속하면 바로 403
  • 파일은 업로드했는데 “접근 권한 없음”

가장 흔한 원인

  • 홈 디렉터리에 index 파일이 없음 (정적 호스팅 방식일 때 특히 흔함)
  • 디렉터리/파일 읽기 권한 부족
  • 실행형 파일(스크립트) 권한/설정이 어긋남

해결 순서

  1. 배포 타입 확인: 정적 사이트(HTML)인지, Node 서버(Express/Nest)인지부터 분리
  2. 정적이라면: 루트에 index.html 존재 여부 확인
  3. Node 서버라면: “웹서버가 정적 파일을 찾다 403”인지 “리버스 프록시 앞단 403”인지 로그로 분리

📌 이미지 삽입 위치 #3 (예: “403 화면 + 서버 디렉터리 구조”)

2) 404 Not Found (라우팅/정적 경로/빌드 산출물 누락)

증상

  • 루트(/)는 뜨는데 특정 경로만 404
  • 새로고침 시 SPA 라우팅이 404
  • Next.js 배포 후 /_next/static/...가 404

원인 TOP 4

  1. URL 오타 또는 실제 파일/라우트가 없음
  2. SPA(React/Vue)인데 서버가 history fallback을 안 해줌
  3. 정적 파일 경로(express.static)가 실제 폴더와 불일치
  4. Next/Nuxt 등 빌드 산출물 폴더가 서버에 없음(빌드 안 했거나 업로드 누락)

즉시 해결 팁

  • Express라면 정적 폴더 경로를 먼저 확정:
    app.use("/static", express.static(path.join(__dirname, "public")))
  • SPA 새로고침 404라면, 서버가 index.html로 fallback하도록 설정(환경에 따라 Nginx/앱 레벨 처리)
  • Next.js라면:
    • npm run buildnpm start 순서가 지켜졌는지
    • .next 폴더가 실제로 생성/배포되어 있는지

📌 이미지 삽입 위치 #4 (예: “SPA 새로고침 404 재현 화면”)

3) 500 Internal Server Error (앱 크래시/환경변수/런타임 예외)

증상

  • 배포 직후 바로 500
  • 특정 API만 500
  • 로그에 TypeError, Cannot read properties of undefined 같은 런타임 에러

원인

  • 환경변수 누락: DB URL, JWT SECRET, API KEY 등
  • Node 버전 불일치: 로컬은 최신, 서버는 낮은 버전이라 문법/패키지 호환 깨짐
  • 빌드/실행 순서 오류: build 없이 start만 수행
  • 권한/경로 문제: 업로드 경로가 달라서 파일을 못 읽음

해결 순서(가장 빨리 잡히는 루트)

  1. 로그 200줄 확보: (PM2라면) pm2 logs myapp --lines 200
  2. 환경변수 체크: 서버에서 printenv 또는 앱 설정 화면에서 누락 여부 확인
  3. Node 버전 고정:
    • .nvmrc 또는 engines로 버전 명시
    • "engines": { "node": ">=18" } (예시)

📌 이미지 삽입 위치 #5 (예: “pm2 logs에서 첫 에러 줄 하이라이트”)

4) 502 Bad Gateway / 503 Service Unavailable (프록시/프로세스 다운/포트 문제)

증상

  • 처음엔 되다가 어느 순간 502
  • 배포 직후 503으로 고정
  • 서버는 살아있는데 웹에서만 접속 불가

가장 흔한 원인 6가지

  1. 앱 프로세스가 꺼짐 (PM2 미사용, 크래시, 메모리 초과)
  2. 포트 불일치: 앱은 3000에 뜨는데 프록시는 다른 포트를 바라봄
  3. PORT 환경변수 무시: 코드에서 포트를 하드코딩
  4. 헬스체크 실패: 앱이 부팅이 너무 느리거나(SSR/DB 연결 지연) 타임아웃
  5. 리버스 프록시 헤더/프로토콜: https 뒤에 http 앱이 있고, 리다이렉트 루프
  6. 도메인 연결 직후 전파(캐시/설정 적용 지연)

즉시 해결(실전 루틴)

  1. PM2 상태 확인
    pm2 list
    pm2 logs myapp --lines 200
  2. 서버가 실제로 포트를 듣는지 확인 (가능한 범위에서)
    # 환경에 따라 netstat/ss 사용 가능
    # ss -lntp | grep 3000
  3. 코드가 PORT를 사용하도록 강제
    const port = Number(process.env.PORT) || 3000;
    app.listen(port, () => console.log("listen:", port));
  4. 프로세스 자동 재시작/관리를 PM2로 고정
    npm i -g pm2
    pm2 start index.js --name myapp
    pm2 save

📌 이미지 삽입 위치 #6 (예: “502 화면 + pm2 list 상태(online/offline)”)

5) “npm start가 안 돼요” (package.json 스크립트/실행 파일 문제)

증상

  • 배포는 됐는데 서버가 안 뜸
  • npm start 실행 시 아무 것도 안 하거나 즉시 종료

원인

  • package.jsonscripts.start가 없거나, 개발용(nodemon)으로만 되어 있음
  • 엔트리 파일명이 실제 파일과 다름(index.js라 해놓고 server.js만 존재)
  • TypeScript인데 빌드 없이 node src/index.ts로 실행하려는 실수

해결

{
  "scripts": {
    "start": "node index.js",
    "build": "tsc -p tsconfig.json"
  }
}

TypeScript라면 보통 npm run builddist를 만든 뒤, "start": "node dist/index.js" 형태로 운영 실행 파일을 분리하는 게 안전합니다.

📌 이미지 삽입 위치 #7 (예: “package.json scripts 설정 캡처”)

6) 정적 파일(CSS/JS/이미지)이 안 뜸 (경로/빌드/정적 서빙)

증상

  • 페이지는 뜨는데 CSS가 적용 안 됨
  • 이미지만 404

원인

  • 정적 폴더를 서버가 서빙하지 않음
  • 빌드 산출물 경로와 서버 정적 경로 불일치
  • 상대경로(./assets)가 배포 경로에서 깨짐

해결 예시(Express)

import path from "path";
import express from "express";

const app = express();
app.use(express.static(path.join(process.cwd(), "public"))); // public 폴더를 정적으로 공개

app.get("/", (req, res) => {
  res.sendFile(path.join(process.cwd(), "public", "index.html"));
});

📌 이미지 삽입 위치 #8 (예: “정적 파일 404 네트워크 탭 캡처”)

7) 운영에서만 터지는 CORS/쿠키/세션 문제

증상

  • 로컬에서는 로그인 되는데 운영에서는 쿠키가 안 붙음
  • 프론트-백엔드 분리 시 CORS 에러

원인

  • SameSite/secure 설정이 HTTPS 환경에서 달라짐
  • Origin이 다르지만 서버가 허용을 안 함
  • 프록시 뒤에서 실제 프로토콜 판단 실패(trust proxy 미설정)

해결 방향(정답 공식)

  • 쿠키 기반 인증이라면: HTTPS 운영에서 secure: true + SameSite 정책 재점검
  • 프록시 환경이라면: Express의 app.set("trust proxy", 1) 고려
  • CORS는 허용 Origin을 정확히 화이트리스트로 제한 (와일드카드로 때우면 운영 보안이 망가짐)

📌 이미지 삽입 위치 #9 (예: “CORS 에러 콘솔 로그 캡처”)

8) 최종: 배포 실패를 ‘습관’으로 막는 운영 템플릿

운영 배포 기본 루틴(추천)

# 1) 코드 업로드(SFTP/Git 등)
# 2) 의존성 설치
npm ci

# 3) 빌드(필요한 경우)
npm run build

# 4) PM2로 실행/갱신
pm2 start index.js --name myapp
pm2 save

# 5) 장애 나면: 로그부터
pm2 logs myapp --lines 200

실전 팁 5개

  • 엔트리 파일명start 스크립트는 문서로 박아두기 (팀이면 더 중요)
  • PORT 하드코딩 금지 (운영은 환경변수가 진짜다)
  • 빌드 결과물은 “서버에 존재하는지”를 파일 트리로 검증
  • 로그는 첫 줄이 핵심: 연쇄 에러가 아니라 “최초 원인”을 잡기
  • 문제 재발 시, 체크리스트를 PR 템플릿에 넣어 자동화

마무리

가비아 호스팅에서 Node.js 배포가 어려운 이유는, 대부분이 “한 번에 다 바꿔서”입니다. 403/404/500/502/503을 만나면 로그 → 프로세스(PM2) → 포트(PORT) → 빌드 산출물 순서로 좁혀가면 복구 속도가 확 빨라집니다.

다음 글에서는 “가비아 + PM2 + 무중단(reload) + 로그 로테이션”까지 운영 세팅을 묶어서 배포 템플릿으로 만들어드릴게요.


Meta Description (160자)

가비아 Node.js 호스팅 배포에서 자주 터지는 403/404/500/502/503 오류를 원인별로 정리하고, PM2·PORT·빌드 산출물·권한·라우팅 체크리스트로 빠르게 복구하는 실전 해결법을 안내합니다.

태그 10개

Node.js, 가비아호스팅, 서버배포, PM2, 502BadGateway, 503ServiceUnavailable, 500InternalServerError, Express배포, Nextjs배포, 리버스프록시

반응형