본문으로 건너뛰기

개발 환경 설정 가이드

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최초 작성