앞서 2장, 3장에서 nestjs를 통해 서버를 구현해보고 Dockerfile을 통해 postgres와 redis를 컨테이너화 하는 작업을 진행했다.
이번 장에서는 2장과 3장에서 했던 예제를 토대로 postgre를 nestjs에 postgres를 연결시켜주는 작업을 진행해보자.
핵심 : nestjs로 프로젝트를 만들어 뒀다면 해당 프로젝트를 컨테이너화 할때 패키지를 재설치 할 필요값없다!
우선 package에 대해 알아보자.
nestjs예제를 만들때 아래 예제 처럼 여러가지의 패키지를 다운 받았다. python같은 경우 이런식으로 패키지를 다운 받으면, 로컬에있는 라이브러리 폴더에 저장되어 다른 프로젝트를 생성하더라도 해당 패키지가 공유되는 방식이다.
ex) npm install pg typeorm @nestjs/typeorm --save
그래서 python의 방식으로 패키지가 다운된다면, docker 컨테이너에서 package를 재설치해야하나? dockerfile을 통해 npm설치를 다시 해야하나 고민에 빠지게 된다.
하지만 걱정없다. npm package의 경우 기본적으로 패키지 설치를 진행한 모듈 내에서 패키지가 설치된다.
무슨말이냐고 아래그림을 보라. 만약 니가 myproject를 진행중인데, moment 패키지를 설치하면, 해당 프로젝트 내에 패키지가 설치되게된다. 그래서 다른 프로젝트와 공유하지도 않는다.
만약 공유하게 설치를 하고 싶다면 아래 그림처럼 따로 폴더를 만들어 상위 폴더로 이동하는 방법도 있다. 어찌됐든 중요한건 패키지를 컨테이너화 한다고 해서 따로 설치할 필요가 없다는것이다. 그냥 컨테이너에 nestjs진행 프로젝트를 복사해주기만 하면 그대로 사용가능하다.
docker-compose up을 진행할때 --build옵션과 함께 진행하길 권장한다. 위에서 본대로 nestjs에 대한 동작은 dockerfile에서 COPY를 통해 파일을 컨테이너에 넘겨서 실행한다.
만약 --build없이 compose를 진행하면, 이미 같은이름으로 만들어진 images가 있을경우 images를 건너띄고 빌드할수도 있다. 그럼 변경사항이 적용되지 않는다. 이를 대비하기 위해 --build옵션을 추가해서 진행하자.
To fix this, we can run the following command:
docker-compose up --build -V
--build :필요하지 않은 경우에도 강제로 이미지를 빌드해야합니다.
-V : 모든 익명 볼륨을 제거하고 다시 생성합니다.
자 이제 전반적인 지식은 끝났고 이제 postgres를 nestjs와 연결해보자 .
우선 nestjs의 객채를 postgres의 테이블과 교환하려면 typeorm을 이용해 객체를 entity로 바꾸고 entity를 테이블 형태로 바꾸는 식으로 진행된다고 앞서 2장에서 공부했다.
아래 예제는 tyeporm에 설정한 내용들이다.
이번 시간에는 설정들을 env를 이용해 진행할것이다. env에 대한 값들을 잘 살펴보자!
typeorm이란? 객체-관계 매핑 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해준다.
import { TypeOrmModuleOptions } from "@nestjs/typeorm";
import * as config from 'config';
const dbConfig = config.get('db');
console.log('db :', dbConfig);
// console.log('host :', dbConfig.host);
export const typeORMConfig : TypeOrmModuleOptions = {
type: 'postgres',
host: process.env.RDB_HOSTNAME || dbConfig.host,
port: process.env.RDB_PORT || dbConfig.port,
username: process.env.RDB_USERNAME || dbConfig.username,
password: process.env.RDB_PASSWORD || dbConfig.password,
database: process.env.RDB_DATABASE || dbConfig.database,
entities: [__dirname + '/../**/*.entity.{js,ts}'],
synchronize: dbConfig.synchronize
};
env로 설정을 진행하기 위해 yml파이를 살펴보아야한다.
nestjs에서 env설정은 보통 .env파일처럼 하나의 파일로 env 설정을 제어하는걸 권장한다.(다른것도 비슷하겟지만,좀더 권장한단다.)
env값들은 build할때 넣어주는데, 우리는 빌드를 yml파일로 docker-compose로 진행했으므로 yml파일의 설정을 해주면 된다.
.env로 설정하기 위해 아래 예제처럼 env_file에 해당 파일을 지정해주었다.
version: '3.7'
services:
main:
container_name: main
build:
context: . ## Dockerfile이 있는 경로 (절대경로 또는 상대경로)
target: development ## targetmulti-stage 내부에 정의된 대로 빌드할 단계를 정의합니다 Dockerfile
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
## - ${SERVER_PORT}:${SERVER_PORT} # 검색되면 쓰고 아니면 아래 포트로 연결된다.
- 8090:3000 # // 호스트 포트:컨테이너 포트, docker run -p 8090:3000 main이랑 같음. - 8090:3000
command: npm run start:dev
env_file:
- .env
아래 처럼 설정하면된다. typeorm.config.ts에 환경변수로 설정할거기 떄문에 굳이 env를 안쓰고 바로 대입해줘도 되겟지만, env도 배우고 설정도 해보고 일석이조다.
RDB_HOSTNAME=postgres
RDB_PORT=5432
RDB_PASSWORD=postgres
RDB_USERNAME=postgres
RDB_DATABASE=postgres
이제 postgres 컨테이너를 만들 때 비밀번호와 해당 컨테이너의 포트번호를 설정해주면된다.
POSTGRES_PASSWORD에 만들고 싶은 비밀번호를 넣어주면 컨테이너를 생성할때 postgres의 비밀번호가 지정된다.
volumes는 데이터가 저장될 경로와 해당 경로에서 사용할 파일 이름을 지어주면 된다.(api-db) 만약 이름을 지어주지 않으면 임의의 이름으로 지어주기 떄문에 나중에 혼돈을 줄수 있다.!
postgres:
image: postgres
ports:
- "5432:5432"
environment:
POSTGRES_DB: "postgres"
POSTGRES_PASSWORD: "postgres"
POSTGRES_USER: "postgres"
POSTGRES_DB: "postgres"
#PG_DATA: /var/lib/postgresql/data
#POSTGRES_HOST_AUTH_METHOD: "trust"
networks:
- webnet
volumes:
- api-db:/var/lib/postgresql/data
#- /var/lib/postgresql/data
#- pgdata:/var/lib/postgresql/data
networks:
webnet:
volumes:
api-db:
# pgdata:
아래 명령을 입력하면 실행중인 컨테이너를 모두 종료할수 있다!
docker rm -f $(docker ps -qa)