언제 쓰는가
NestJS 프로젝트에서 Docker Compose로 PostgreSQL 컨테이너를 띄우고, @nestjs/typeorm, typeorm, pg를 사용해서 NestJS 애플리케이션과 DB를 연결할 때 본다.
현재 예시 프로젝트:
/Users/littleduck/Documents/GitHub/coding_study/Frameworks/nestjs_server
전체 흐름
- NestJS 프로젝트에 TypeORM 관련 패키지를 설치한다.
docker-compose.yaml에 PostgreSQL 서비스를 만든다.- Docker Compose로 PostgreSQL 컨테이너를 실행한다.
AppModule에서TypeOrmModule.forRoot()로 PostgreSQL 접속 정보를 등록한다.- NestJS 서버를 실행해서 DB 연결 에러가 없는지 확인한다.
1. 패키지 설치
NestJS에서 TypeORM과 PostgreSQL을 쓰려면 아래 패키지가 필요하다.
npm install @nestjs/typeorm typeorm pg
현재 프로젝트의 package.json에는 아래 의존성이 들어가 있다.
{
"@nestjs/typeorm": "^11.0.1",
"pg": "^8.21.0",
"typeorm": "^1.0.0"
}
역할:
@nestjs/typeorm: NestJS에서 TypeORM을 모듈로 연결하게 해준다.typeorm: ORM 본체다.pg: Node.js에서 PostgreSQL에 접속하기 위한 드라이버다.
2. Docker Compose 작성
프로젝트 루트에 docker-compose.yaml을 만든다.
services:
postgres:
image: postgres:15
restart: always
volumes:
- ./postgres-data:/var/lib/postgresql/data
ports:
- '5432:5432'
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
각 항목 의미:
image: postgres:15: PostgreSQL 15 버전 이미지를 사용한다.restart: always: 컨테이너가 꺼지면 자동으로 다시 실행한다.volumes: DB 데이터를 프로젝트의postgres-data폴더에 저장한다.ports: 로컬 Mac의5432포트를 컨테이너의5432포트에 연결한다.POSTGRES_USER: DB 사용자 이름이다.POSTGRES_PASSWORD: DB 비밀번호다.POSTGRES_DB: 처음 생성할 DB 이름이다.
이 설정에서는 사용자, 비밀번호, DB 이름이 모두 postgres다.
3. PostgreSQL 컨테이너 실행
프로젝트 루트에서 실행한다.
docker compose up -d
실행 상태 확인:
docker compose ps
로그 확인:
docker compose logs postgres
컨테이너 중지:
docker compose down
DB 데이터까지 완전히 지우고 새로 시작하고 싶으면 postgres-data 폴더를 삭제한 뒤 다시 실행한다.
docker compose down
rm -rf postgres-data
docker compose up -d
주의: postgres-data를 삭제하면 로컬 DB 데이터가 전부 사라진다.
4. NestJS에서 TypeORM 연결
src/app.module.ts에서 TypeOrmModule을 import한다.
import { TypeOrmModule } from '@nestjs/typeorm';
그리고 imports 배열에 TypeOrmModule.forRoot()를 추가한다.
@Module({
imports: [
PostsModule,
TypeOrmModule.forRoot({
type: 'postgres',
host: '127.0.0.1',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'postgres',
entities: [],
synchronize: true,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
설정값은 docker-compose.yaml과 맞아야 한다.
| TypeORM 설정 | Docker Compose 설정 | 현재 값 |
|---|---|---|
host |
로컬에서 접속하므로 127.0.0.1 |
127.0.0.1 |
port |
ports의 왼쪽 값 |
5432 |
username |
POSTGRES_USER |
postgres |
password |
POSTGRES_PASSWORD |
postgres |
database |
POSTGRES_DB |
postgres |
synchronize: true는 엔티티 기준으로 DB 테이블을 자동 동기화한다.
개발 중에는 편하지만 운영 환경에서는 보통 false로 둔다.
synchronize: false
5. NestJS 서버 실행
PostgreSQL 컨테이너가 떠 있는 상태에서 NestJS 서버를 실행한다.
npm run start:dev
서버가 정상 실행되고 TypeORM 관련 접속 에러가 없으면 연결 성공이다.
빠른 재실행 순서
이미 설정이 끝난 프로젝트라면 보통 아래 순서만 기억하면 된다.
docker compose up -d
npm run start:dev
상태 확인:
docker compose ps
docker compose logs postgres
자주 나는 문제
1. 포트 5432가 이미 사용 중
증상:
Bind for 0.0.0.0:5432 failed: port is already allocated
원인:
로컬 PostgreSQL이나 다른 Docker 컨테이너가 이미 5432 포트를 쓰고 있다.
해결 방법:
docker-compose.yaml에서 왼쪽 포트를 바꾼다.
ports:
- '5433:5432'
그리고 TypeORM 설정의 port도 같이 바꾼다.
port: 5433,
2. password authentication failed
증상:
password authentication failed for user "postgres"
원인:
TypeORM의 username, password, database 값이 Docker Compose의 환경 변수와 다르거나, 기존 postgres-data에 예전 비밀번호로 초기화된 DB가 남아 있다.
확인할 값:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
username: 'postgres',
password: 'postgres',
database: 'postgres',
기존 데이터를 지우고 다시 만들려면:
docker compose down
rm -rf postgres-data
docker compose up -d
주의: 로컬 DB 데이터가 삭제된다.
3. connect ECONNREFUSED 127.0.0.1:5432
증상:
connect ECONNREFUSED 127.0.0.1:5432
원인:
PostgreSQL 컨테이너가 실행 중이 아니거나 포트가 다르다.
확인:
docker compose ps
docker compose logs postgres
해결:
docker compose up -d
4. Entity를 만들었는데 테이블이 안 생김
현재 설정은 아래처럼 비어 있다.
entities: [],
엔티티 클래스를 만들었다면 entities에 추가하거나 자동 로딩을 켠다.
예시:
TypeOrmModule.forRoot({
type: 'postgres',
host: '127.0.0.1',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'postgres',
autoLoadEntities: true,
synchronize: true,
});
그리고 각 기능 모듈에서 엔티티를 등록한다.
TypeOrmModule.forFeature([PostEntity])
체크리스트
docker-compose.yaml이 프로젝트 루트에 있는가?docker compose up -d후docker compose ps에서postgres가 실행 중인가?- 로컬 접속 포트와 TypeORM의
port가 같은가? POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB와 TypeORM 설정이 같은가?- NestJS 서버 실행 시 TypeORM 접속 에러가 없는가?
- 엔티티를 만들었다면
entities또는autoLoadEntities설정을 했는가?
관련 파일
/Users/littleduck/Documents/GitHub/coding_study/Frameworks/nestjs_server/docker-compose.yaml/Users/littleduck/Documents/GitHub/coding_study/Frameworks/nestjs_server/src/app.module.ts/Users/littleduck/Documents/GitHub/coding_study/Frameworks/nestjs_server/package.json