본문으로 건너뛰기

개발 환경 설정 가이드

1. 필수 소프트웨어 설치

1.1 필수 도구

  • Node.js v20 이상 (v20.9.0 LTS 권장)
  • Yarn Berry v4.6 이상 (v4.6.0 권장)
  • Git v2.43 이상
  • Docker Desktop v4.39 이상
  • Cursor (최신 버전)
  • NX CLI v20.6.0

1.2 설치 방법

macOS

# Homebrew 설치 (없는 경우)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Node.js 설치 (nvm 권장)
brew install nvm
nvm install 20.9.0
nvm use 20.9.0
nvm alias default 20.9.0

# Cursor 설치
brew install --cask cursor

# Git 설치
brew install git

# Docker Desktop 설치
brew install --cask docker

# Yarn Berry 설치
corepack enable
corepack prepare yarn@4.6.0 --activate

# NX CLI 설치
yarn global add @nx/cli@20.6.0

Windows

  1. Node.js 공식 사이트에서 v20.9.0 LTS 버전 설치
  2. Git v2.43 이상 설치
  3. Docker Desktop v4.39 이상 설치
  4. Cursor 최신 버전 설치
  5. 관리자 권한으로 PowerShell을 실행하여 다음 명령어 실행:
    # Yarn Berry 설치
    corepack enable
    corepack prepare yarn@4.6.0 --activate

    # NX CLI 설치
    yarn global add @nx/cli@20.6.0

1.3 설치 확인

# 버전 확인
node --version # v20.9.0
yarn --version # 4.6.0
git --version # 2.43.x 이상
nx --version # 20.6.0
docker --version # 24.0.x 이상

2. 프로젝트 설정

2.1 저장소 클론

git clone [repository-url]
cd dta-wide-mono

2.2 Yarn Berry 설정

# Yarn Berry 활성화
yarn set version 4.6.0

# 의존성 플러그인 설치
yarn plugin import workspace-tools
yarn plugin import typescript
yarn plugin import interactive-tools

# Zero-install 설정
yarn config set nodeLinker node-modules

# .gitignore 설정
echo ".yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions" > .gitignore

2.3 NX 워크스페이스 설정

중요: DTA-WIDE 모노레포 설계 원칙, 구조, 명명 규칙 및 모범 사례에 대한 자세한 내용은 NX 모노레포 가이드라인을 참조하세요.

# 저장소 클론 후 의존성 설치
yarn install

# 개발 서버 실행
nx serve dta-wide-api

프로젝트 생성 명령어 참조

주요 NX 프로젝트 생성 명령어는 다음과 같습니다:

# NestJS 애플리케이션 생성
nx g @nx/nest:app dta-wide-api --directory=apps/dta-wide-api --tags=scope:api

# 기타 생성 명령어와 모노레포 관리에 관한 상세 내용은
# /infrastructure/nx/monorepo-guidelines 문서를 참고하세요.

3. 환경 변수 설정

3.1 GCP 서비스 계정 설정

  1. GCP 콘솔에서 서비스 계정 키(dta-wide-api-credentials.json) 다운로드
  2. 프로젝트의 해당 앱 디렉토리로 이동 후 credentials 디렉토리 생성하고 키 파일 저장:
    # 앱 디렉토리로 이동
    cd apps/dta-wide-api

    # credentials 디렉토리 생성
    mkdir -p credentials

    # 서비스 계정 키 파일 이동
    mv ~/Downloads/dta-wide-api-credentials.json credentials/
  3. 환경 변수 설정:
    # macOS/Linux
    export GOOGLE_APPLICATION_CREDENTIALS="./credentials/dta-wide-api-credentials.json"

    # Windows PowerShell
    $env:GOOGLE_APPLICATION_CREDENTIALS=".\credentials\dta-wide-api-credentials.json"

중요: 서비스 계정 키 파일은 반드시 해당 앱의 credentials 디렉토리에 위치해야 합니다. 이는 Cloud Run 배포 시 /app/credentials 경로에 마운트되는 구조와 일치합니다.

3.2 환경 변수 설정

GCP Secret Manager를 통해 환경 변수를 관리합니다. 로컬 개발 환경에서는 다음과 같은 환경 변수가 필요합니다:

# GCP 프로젝트 설정
CLOUD_PROJECT_ID=your-project-id
RUNTIME_ENV=local # local, development, stage, production
SERVICE_NAME=dta-wide-api

# GCP 서비스 계정 키 파일 경로
GOOGLE_APPLICATION_CREDENTIALS=./credentials/dta-wide-api-credentials.json

중요:

  • 서비스 계정 키 파일은 절대 Git에 커밋하지 마세요.
  • 프로덕션 환경의 환경 변수는 GCP Secret Manager에서 관리됩니다.
  • 로컬 개발 시에도 가능한 한 Secret Manager를 사용하는 것을 권장합니다.

macOS/Linux 환경 설정

# ~/.zshrc 또는 ~/.bashrc에 추가
export CLOUD_PROJECT_ID=your-project-id
export RUNTIME_ENV=local
export SERVICE_NAME=dta-wide-api
export GOOGLE_APPLICATION_CREDENTIALS=./credentials/dta-wide-api-credentials.json

Windows PowerShell 환경 설정

# 사용자 환경 변수에 추가
[Environment]::SetEnvironmentVariable("CLOUD_PROJECT_ID", "your-project-id", "User")
[Environment]::SetEnvironmentVariable("RUNTIME_ENV", "local", "User")
[Environment]::SetEnvironmentVariable("SERVICE_NAME", "dta-wide-api", "User")
[Environment]::SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", "./credentials/dta-wide-api-credentials.json", "User")

VS Code 설정

.vscode/settings.json 파일에 다음 설정을 추가하면 디버깅 시에도 환경 변수가 적용됩니다:

{
"terminal.integrated.env.osx": {
"CLOUD_PROJECT_ID": "your-project-id",
"RUNTIME_ENV": "local",
"SERVICE_NAME": "dta-wide-api",
"GOOGLE_APPLICATION_CREDENTIALS": "./credentials/dta-wide-api-credentials.json"
},
"terminal.integrated.env.linux": {
"CLOUD_PROJECT_ID": "your-project-id",
"RUNTIME_ENV": "local",
"SERVICE_NAME": "dta-wide-api",
"GOOGLE_APPLICATION_CREDENTIALS": "./credentials/dta-wide-api-credentials.json"
},
"terminal.integrated.env.windows": {
"CLOUD_PROJECT_ID": "your-project-id",
"RUNTIME_ENV": "local",
"SERVICE_NAME": "dta-wide-api",
"GOOGLE_APPLICATION_CREDENTIALS": "./credentials/dta-wide-api-credentials.json"
}
}

4. 데이터베이스 설정

4.1 Cloud SQL Proxy 설정

  1. Cloud SQL Proxy 설치:
# macOS
brew install cloud_sql_proxy

# Linux
wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
chmod +x cloud_sql_proxy
sudo mv cloud_sql_proxy /usr/local/bin/

# Windows (PowerShell)
Invoke-WebRequest https://dl.google.com/cloudsql/cloud_sql_proxy.windows.amd64.exe -OutFile cloud_sql_proxy.exe
  1. Cloud SQL Proxy 실행 스크립트 생성:
# start_db_proxy.sh 생성
cat > start_db_proxy.sh << 'EOF'
#!/bin/bash
./cloud_sql_proxy -instances=\
dta-cloud-de-dev:europe-west3:db-dta-wide-dev=tcp:5433,\
dta-cloud-de-stage:europe-west3:db-dta-wide-stage=tcp:5533,\
dta-cloud-de-prod:europe-west3:db-dta-wide-prod=tcp:5633
EOF

# 실행 권한 부여
chmod +x start_db_proxy.sh
  1. Cloud SQL Proxy 실행:
# 백그라운드로 실행
./start_db_proxy.sh &

# 또는 별도 터미널에서 실행
./start_db_proxy.sh

포트 매핑 정보:

  • DEV DB: localhost:5433
  • STAGE DB: localhost:5533
  • PROD DB: localhost:5633

4.2 Redis 설정

  1. Redis 터널링 스크립트 생성:
# start_redis_tunnel.sh 생성
cat > start_redis_tunnel.sh << 'EOF'
#!/bin/bash

source .env.redis.dev

gcloud config set project $CLOUD_PROJECT_ID

gcloud compute ssh redis-tunnel --zone=europe-west3-a -- -N -L $REDIS_PORT:$REDIS_HOST:$REDIS_PORT
EOF

# 실행 권한 부여
chmod +x start_redis_tunnel.sh
  1. 환경 변수 파일 생성:
# .env.redis.dev 생성
cat > app.env.redis.dev << 'EOF'
CLOUD_PROJECT_ID=dta-cloud-de-dev
REDIS_HOST=10.x.x.x # Redis 내부 IP
REDIS_PORT=6379
EOF
  1. Redis 터널 실행:
# 별도 터미널에서 실행 (백그라운드 실행 비권장)
./start_redis_tunnel.sh

주의사항:

  • Redis 터널링은 별도의 터미널 창에서 실행하는 것을 권장합니다.
  • 터널링이 끊어지면 Redis 연결도 끊어집니다.
  • Redis 호스트 정보는 Secret Manager에서 확인할 수 있습니다.
  • GCP 프로젝트에 대한 적절한 권한이 필요합니다.

4.3 데이터베이스 마이그레이션

# 마이그레이션 실행
nx run dta-wide-api:migrate

# 시드 데이터 생성 (필요한 경우)
nx run dta-wide-api:seed

데이터베이스 관련 주의사항:

  • Cloud SQL Proxy는 GCP 서비스 계정 인증이 필요합니다. 3.1 GCP 서비스 계정 설정이 완료되어 있어야 합니다.
  • 프로덕션 DB 접근은 특별한 경우에만 사용하세요.
  • 각 데이터베이스 접속 정보는 Secret Manager에서 관리됩니다.
  • 마이그레이션 실행 전에 항상 변경 내용을 확인하세요.
  • 문제 발생 시 다음 명령어로 상태를 확인할 수 있습니다:
    # 마이그레이션 상태 확인
    nx run dta-wide-api:migrate:status

    # 마이그레이션 이력 조회
    nx run dta-wide-api:migrate:history

5. IDE 설정

5.1 VS Code 확장 프로그램

필수 확장 프로그램:

  • ESLint
  • Prettier
  • NX Console
  • Docker
  • GitLens
  • Error Lens

5.2 VS Code 설정

.vscode/settings.json 파일에 다음 설정을 추가합니다:

{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.preferences.importModuleSpecifier": "non-relative",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

5.3 디버깅 설정

.vscode/launch.json 파일에 다음 설정을 추가합니다:

{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug API",
"program": "${workspaceFolder}/node_modules/@nx/cli/bin/nx.js",
"args": ["serve", "dta-wide-api"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}

6. 로컬 개발 가이드

6.1 개발 서버 실행

# API 서버 실행
nx serve dta-wide-api

# 여러 프로젝트 동시 실행
nx run-many -t serve -p dta-wide-api web --parallel

6.2 NestJS 애플리케이션 구현 시작하기

NX를 사용하여 NestJS 애플리케이션을 생성한 후, 기본 골격을 구현하는 방법을 설명합니다. 이 단계는 공통 라이브러리나 도메인 모듈을 구현하기 전의 초기 단계입니다.

6.2.1 주요 파일 구조

NX로 생성된 NestJS 애플리케이션은 다음과 같은 주요 파일 구조를 가집니다:

apps/dta-wide-api/
├── src/
│ ├── app/ # 애플리케이션 코드
│ │ ├── app.controller.ts # 기본 컨트롤러
│ │ ├── app.module.ts # 루트 모듈
│ │ ├── app.service.ts # 기본 서비스
│ ├── main.ts # 애플리케이션 진입점
│ ├── assets/ # 정적 파일
│ └── environments/ # 환경 설정
├── project.json # NX 프로젝트 설정
└── tsconfig.json # TypeScript 설정

6.2.2 기본 애플리케이션 부트스트랩 구현 (main.ts)

애플리케이션의 진입점인 main.ts 파일의 기본 구현입니다. 이후 애플리케이션 부트스트랩 프로세스 문서를 참고하여 기능을 확장할 수 있습니다.

// apps/dta-wide-api/src/main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';

import { AppModule } from './app/app.module';

async function bootstrap() {
try {
// NestJS 애플리케이션 인스턴스 생성
const app = await NestFactory.create(AppModule);

// 기본 설정
const port = process.env.PORT || 3000;
const apiPrefix = process.env.API_PREFIX || 'api';

// API 접두사 설정
app.setGlobalPrefix(apiPrefix);

// CORS 설정
app.enableCors();

// 유효성 검증 파이프라인 설정
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true,
})
);

// Swagger UI 설정
const options = new DocumentBuilder()
.setTitle('DTA WIDE API')
.setDescription('DTA WIDE API 문서')
.setVersion('0.1.0')
.build();

const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup(`${apiPrefix}/docs`, app, document);

// 서버 리스닝 시작
await app.listen(port);
console.log(`Application is running on: ${await app.getUrl()}`);
} catch (error) {
console.error('Bootstrap error:', error);
process.exit(1);
}
}

bootstrap();

6.2.3 기본 루트 모듈 구현 (app.module.ts)

애플리케이션의 루트 모듈 기본 골격입니다. 이후 개발이 진행됨에 따라 필요한 모듈을 추가할 수 있습니다.

// apps/dta-wide-api/src/app/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

// 자체 컴포넌트 임포트
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
imports: [
// 환경 설정 모듈
ConfigModule.forRoot({
isGlobal: true,
envFilePath: ['.env.local', '.env'],
}),

// 추가 모듈은 개발 진행에 따라 여기에 추가합니다
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

6.2.4 기본 컨트롤러 구현 (app.controller.ts)

기본 컨트롤러 구현입니다. 이는 애플리케이션이 정상적으로 실행되는지 확인하기 위한 헬스 체크 엔드포인트를 제공합니다.

// apps/dta-wide-api/src/app/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}

@Get()
getHello(): string {
return this.appService.getHello();
}

@Get('health')
getHealth() {
return {
status: 'ok',
timestamp: Date.now(),
service: 'dta-wide-api',
version: '0.1.0',
};
}
}

6.2.5 기본 서비스 구현 (app.service.ts)

기본 서비스 구현입니다.

// apps/dta-wide-api/src/app/app.service.ts
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
getHello(): string {
return 'Welcome to DTA WIDE API!';
}
}

6.2.6 필요한 패키지 설치

애플리케이션 구현에 필요한 기본 패키지를 설치합니다.

# 기본 패키지 설치
yarn add @nestjs/config @nestjs/swagger class-validator class-transformer

# 개발 의존성 설치
yarn add -D @types/node @types/express

6.2.7 개발 모드로 실행 및 테스트

기본 골격 구현 후 개발 모드로 실행하여 테스트합니다.

# 개발 모드로 실행
nx serve dta-wide-api

# 브라우저에서 확인
# http://localhost:3000/api/health
# http://localhost:3000/api/docs (Swagger UI)

6.2.8 다음 단계

기본 골격이 정상적으로 동작하는 것을 확인했다면, 다음 개발 단계를 진행할 수 있습니다:

  1. 공통 라이브러리 모듈 구현 (core/logging, core/database 등)
  2. 도메인별 기능 모듈 구현 (feature/user, feature/auth 등)
  3. 애플리케이션 부트스트랩 프로세스 확장 (미들웨어, 인터셉터, 필터 등)

참고: 이러한 고급 기능 구현에 대한 내용은 애플리케이션 부트스트랩 프로세스 문서와 NX 모노레포 가이드라인을 참조하세요.

6.3 테스트 실행

# 단위 테스트
nx test dta-wide-api

# E2E 테스트
nx e2e dta-wide-api

# 특정 테스트 파일 실행
nx test dta-wide-api --testFile=auth.spec.ts

# 테스트 커버리지 보고서 생성
nx test dta-wide-api --coverage

6.4 린트 및 포맷팅

# 린트 실행
nx lint dta-wide-api

# 자동 수정
nx lint dta-wide-api --fix

# 포맷팅 검사
nx format:check

# 포맷팅 수정
nx format:write

6.5 빌드

# 프로덕션 빌드
nx build dta-wide-api --prod

# 개발 빌드
nx build dta-wide-api

7. 문제 해결

7.1 일반적인 문제

의존성 문제

# node_modules 삭제 후 재설치
rm -rf node_modules
yarn install

NX 캐시 문제

# 캐시 초기화
nx reset

# 특정 프로젝트 캐시만 초기화
nx reset dta-wide-api

빌드 실패

# 상세 로그 확인
nx build dta-wide-api --verbose

7.2 데이터베이스 문제

# 데이터베이스 재설정
nx run dta-wide-api:migrate:reset

# 데이터베이스 상태 확인
nx run dta-wide-api:migrate:status

7.3 도커 문제

# 컨테이너 상태 확인
docker compose ps

# 로그 확인
docker compose logs -f postgres redis

# 컨테이너 재시작
docker compose restart

8. 참고 자료

변경 이력

버전날짜작성자변경 내용
0.1.02025-03-26bok@weltcorp.com최초 작성