콘텐츠로 이동

Node.js 운영 DB ORM (Sequelize) 사용 기준

운영 서버(Production Server) 환경에서 Node.js 서비스에 Sequelize(ORM)를 적용할 때의
설치 / 초기화 / 모델 생성 / 운영 패턴에 대한 기준을 정리한 문서임.

단순 사용 예제가 아니라,
운영 재현성 / 권한 일관성 / 보안 / 감사 추적 가능성을 전제로 함.

⚠️ 중요
운영 서버에서 /var/www/[ProjectName]/current 경로에서 npm install 수행 ❌
의존성 설치 및 코드 변경은 반드시 /home/[User]/[ProjectName] 또는 동등한 작업 경로에서 수행 후 배포함.


1. 기본 원칙

  • Sequelize 관련 패키지는 프로젝트 로컬 의존성으로 관리함
  • CLI 도구는 전역 설치(npm -g)를 지양하고 npx 사용을 우선함
  • DB 접속 정보(계정/비밀번호)는 파일에 하드코딩 금지
  • 운영 서버에서는 “단발성 작업”이라도 누가 / 어디서 / 어떻게 실행했는지가 명확해야 함
  • 모델 생성 / 마이그레이션 / 시드 작업은 운영 배포 흐름과 분리하여 관리함

2. 설치 기준

2.1 실행 주체 및 경로

  • 아래 명령은 운영 사용자 계정 에서 수행함
  • 수행 위치는 반드시 /home/[User]/[ProjectName] 또는 동등한 작업 경로

/var/www/[ProjectName]/current에서 설치/변경 작업을 하지 않음

2.2 Sequelize 설치 (로컬)

npm install sequelize --save

2.3 CLI / 모델 추출 도구 설치 기준

(권장) 로컬 devDependency + npx 사용

npm install sequelize-cli --save-dev
npm install sequelize-auto --save-dev

실행:

npx sequelize-cli --help
npx sequelize-auto --help
  • 프로젝트별 버전 고정 가능
  • NODE_PATH 설정 불필요
  • 운영 재현성 확보 가능

(비권장) 전역 설치

sudo npm install sequelize-cli --global
sudo npm install sequelize-auto --global

전역 설치는 다음 문제를 유발할 수 있음.

  • 프로젝트 간 버전 충돌
  • 추후 “어떤 버전으로 생성했는지” 추적 불가
  • NODE_PATH 문제 발생 가능

2.4 DB 드라이버 설치 (로컬)

DB 종류에 따라 반드시 로컬 의존성으로 설치함.

DB 종류별 Sequelize 드라이버

DB 종류 패키지 운영 권장
MySQL mysql2
MariaDB mysql2 / mariadb
PostgreSQL pg + pg-hstore
SQLite sqlite3
MSSQL tedious ⚠️
Oracle oracledb ⚠️
  • MySQL
npm install mysql2 --save
  • MariaDB
npm install mariadb --save
  • PostgreSQL
npm install pg pg-hstore --save
  • SQLite
npm install sqlite3 --save
  • Microsoft SQL Server (MSSQL)
npm install tedious --save
  • Oracle
npm install oracledb --save

3. 초기화 (Scaffold 생성)

3.1 실행 주체 / 경로

  • 운영 사용자 계정
  • /home/[User]/[ProjectName] 또는 동등한 작업 경로

3.2 초기화 실행

npx sequelize-cli init

3.3 생성되는 구조

|-- config
|   -- config.json        // DB 설정 파일 (운영 기준에서는 직접 사용하지 않음)
|-- migrations            // DB 스키마 변경 이력. GIT 과 비슷하게, Database 변화 과정들을 추적해나가는 정보로, 실제 Database 에 반영할 수도 있고 변화를 취소할 수도 있음.
|-- models                // DB 각 Table 의 정보를 정의하고 객체 모텔로 정의.
|   -- index.js
|-- seeders               // 초기 데이터 삽입 (선택). Table 에 기본 데이터를 넣고 싶은 경우에 사용.

4. DB 정보 설정 기준 (보안 필수)

4.1 config.json 직접 사용 금지

config/config.json에 계정/비밀번호를 직접 저장하는 방식은 운영에서 금지함.

  • git 유출 위험
  • 파일 권한 노출
  • 로그/백업을 통한 정보 유출 가능성

4.2 운영 권장 방식

  • 환경 변수 기반
  • 또는 config/config.js 사용
// config/config.js
module.exports = {
    production: {
        username: process.env.DB_USER,
        password: process.env.DB_PASS,
        database: process.env.DB_NAME,
        host: process.env.DB_HOST,
        port: Number(process.env.DB_PORT || 3306),
        dialect: process.env.DB_DIALECT || 'mysql',
    },
};

환경 변수는 PM2 ecosystem 또는 systemd 환경 파일로 주입함.


5. 기존 DB에서 Model 추출 (sequelize-auto)

5.1 실행 주체 / 경로

  • 운영 사용자 계정
  • /home/[User]/[ProjectName] 또는 동등한 작업 경로

모델 추출은 코드 생성 작업이므로 /var/www에서 수행하지 않음

5.2 실행 예시 (비밀번호 하드코딩 금지)

export DB_NAME="example_db"
export DB_HOST="127.0.0.1"
export DB_USER="example_user"
export DB_PORT="3306"
export DB_PASS="***"
export DB_DIALECT="mysql"
npx sequelize-auto -o "./models" -d "$DB_NAME" -h "$DB_HOST" -u "$DB_USER" -p "$DB_PORT" -x "$DB_PASS" -e "$DB_DIALECT"

6. 과거 운영 패턴: HTTP 요청으로 DB 초기화 / 모델 생성 트리거

과거 일부 프로젝트에서는 다음과 같은 운영 유틸 패턴을 사용한 사례가 있었음.

  • /Utils/DBTableInitialize/*
    • HTTP 요청으로 DB 기초 데이터(upsert) 수행
  • /Utils/ModelsSequelize/*
    • HTTP 요청으로 sequelize-auto 실행 → 모델 생성

이 패턴의 목적은 운영/스테이징 환경에서 단발성 초기화 작업을 빠르게 수행하는 것이었음.

6.1 왜 이 구조에서 전역 설치(--global)를 사용했는가

이 구조에서는 sequelize-auto가 단순 개발 도구가 아니라 Express 런타임에서 직접 호출되는 실행 파일이었음.

  • 로그인 쉘이 아님 (.bashrc 미적용)
  • 실행 위치가 항상 프로젝트 루트가 아님
  • PATH 기반 실행 보장이 필요함

따라서 당시에는:

npx sequelize-auto ...

를 어디서든 실행 가능하게 하기 위해 전역 설치(--global)를 사용하는 것이 가장 안정적인 선택이었음.

6.2 운영 기준에서 이 패턴을 유지하지 않는 이유

현재 운영 기준에서는 이 패턴을 표준으로 사용하지 않음.

  • HTTP 요청으로 DB 변경 작업 수행 시
    • 인증/권한 미흡 시 외부 호출 위험
    • 실행 이력 감사 어려움
  • GET 요청 기반 트리거는
    • 캐시 / 자동 호출 / 재시도 등으로 오동작 위험
  • HTTP 요청으로 코드 생성(모델 추출) 수행 시
    • 운영 서버에서 파일 변경 발생
    • 배포 재현성 붕괴

6.3 현재 운영 기준

  • 운영 서버에서는 모델 생성 / 코드 생성 작업을 HTTP로 트리거하지 않음
  • 모델 생성은:
    • /home/[User]/[ProjectName] 또는 동등한 작업 경로에서 수행
    • 산출물만 배포 흐름을 통해 /var/www로 반영

6.4 운영 서버 차단 방식 (현재 적용 사례)

운영(Production) 환경에서는 /Utils/* 와 같은 관리/초기화 라우트가
라우팅 등록 단계에서부터 제외됨.

  • NODE_ENV === 'production'
    • /Utils 라우트 미등록
    • /StreaumDocs 라우트 미등록

이 방식은 인증/토큰/IP 제한보다 강한 차단이며,
운영 서버에서 실수 또는 외부 요인으로
DB 초기화 / 모델 생성 / 테스트성 API가 호출되는 사고를 원천 차단함.


7. NODE_PATH 관련 (전역 설치 사용 시에만 발생)

7.1 NODE_PATH 문제 발생 배경 및 실제 대응 사례 (비권장 히스토리)

과거 일부 운영 환경에서는 전역 설치(sudo npm install -g)된 sequelize-auto를 사용하던 구조에서
CLI 실행 시 프로젝트 로컬 node_modules에 설치된 DB 드라이버(mysql2 등)를 찾지 못하는 문제가 발생한 사례가 있었음.

이 문제는 다음 조건이 동시에 충족될 때 발생함.

  • sequelize-auto는 전역 설치(--global)
  • DB 드라이버(mysql2 등)는 프로젝트 로컬 설치
  • 실행 환경이 로그인 쉘이 아님
    • Express 런타임
    • PM2
    • systemd 서비스 등

이로 인해 전역 CLI가 로컬 node_modules 경로를 인식하지 못하여
DB 드라이버 로딩 실패 에러가 발생함.

당시 사용되었던 대응 방식 (히스토리)

당시에는 다음과 같이 NODE_PATH를 수동으로 설정하여 문제를 우회함.

  • root 계정
/etc/profile
export NODE_PATH=/var/www/[ProjectName]/current/node_modules
  • 일반 사용자 계정
/home/[User]/.bashrc
/home/[User]/.bash_profile
export NODE_PATH=/var/www/[ProjectName]/current/node_modules

설정 후에는 다음 절차가 필요했음.

  • 쉘 재로그인 또는 프로세스 재시작
  • 환경 변수 적용 여부 확인

확인

echo $NODE_PATH

이 방식은 당시 환경에서는 실질적인 해결책이었으나, 환경 의존성이 강하고 재현성이 낮아 운영 표준으로 채택하기에는 부적합한 구조였음.

정리

위 NODE_PATH 설정 방식은 과거 운영 환경에서 사용된 우회적 대응 사례이며, 현재 운영 기준에서는 전역 설치를 지양하고
전역 설치를 하지 않고, 로컬 설치 + npx 실행 방식 을 표준으로 사용함. NODE_PATH 설정은 우회책이며 운영 표준은 아님.


8. 정리

  • Sequelize 운영의 핵심은 재현성 + 통제
  • CLI 도구는 로컬 설치 + npx 실행
  • DB 정보는 환경 변수 기반 관리
  • 과거 HTTP 트리거 방식은 이해 가능한 선택이었으나, 현재 운영 기준에서는 보안/감사/재현성 문제로 사용하지 않음
  • 운영 서버에서는 관리/초기화 라우트를 아예 노출하지 않음