EC2 + Docker + ECR로 Nestjs 어플리케이션 배포하기
● Docker 빌드환경 설정하기
프로젝트의 루트폴더에 2개의 파일을 생성해야 한다.
- Dockerfile
- 도커 이미지를 위한 설정파일, 즉 이미지가 어떻게 구성되어있는지 확인할 수 있는 파일이다.
- 도커 이미지를 빌드하면 해당 파일에 적어둔 커맨드를 통해서 이미지가 빌드된다.
# docker의 이미지를 정의, 해당 프로젝트에서 node 16 버전을 사용
FROM node:16
# /app 이라는 폴더에서 프로젝트를 실행할 예정이므로 mkdir 명령어로 폴더를 생성
RUN mkdir -p /app
# /app 이라는 폴더에서 프로젝트를 실행
WORKDIR /app
# Dockerfile이 위치한 폴더의 모든 내용을 /app으로 복사
COPY . .
# 프로젝트에서 사용한 패키지를 package.json 을 통하여 모두 설치
RUN npm install
# 프로젝트를 빌드
RUN npm run build
# 프로젝트에서 5000번 포트를 사용한다는 의미
EXPOSE 5000
# 빌드 이후에 dist라는 폴더에 main.js가 생성되므로 해당 파일을 실행
CMD [ "node", "dist/main.js" ]
- .dockerignore
- Docker 이미지 빌드시 제외하고 싶은 파일을 기재하는 설정파일
.git
Dockerfile
node_modules
.env.development
위 사진과 같이 루트폴더에 생성해준다.
● Docker 빌드하기
우선 프로젝트의 루트폴더로 이동해서 터미널을 열어준다.
그 후 아래 명령어를 입력해서 Docker를 빌드해준다.
docker build -t <도커 이미지명> <Dockerfile 경로>
ex) docker build -t hdev_server .
-t 옵션은 tag의 약자로 태그를 지정할수 있다. 그냥 -t 옵션만 사용할경우 "이미지명:lastest " 으로 이미지가 생성된다.
빌드한 이미지는 "docker images" 명령어로 확인이 가능하다
● AWS ECR 생성 및 Docker 이미지 업로드하기
AWS ECR 이란?
- Elastic Container Registry의 약자로 Docker 이미지를 관리할 수 있는 저장공간이다.
- Docker Hub와 유사하지만 Private 공간도 무료라는 장점이 있다.
- AWS의 자체서비스 이므로 다른 서비스와의 사용이 편하다
생성은 매우 간단하다. 표시는 내부에서만 사용하므로 프라이빗으로 체크해주고 이름만 적어주면 끝난다.
이제 awscli를 사용해서 위에서 빌드한 docker 이미지를 ecr에 푸쉬하면 된다.
1. AWS ECR 도커 인증하기
아래 명령어로 ECR에 대해서 도커로 인증을 진행해준다.
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <ECR URI>
ex) aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin somenumber.dkr.ecr.ap-northeast-2.amazonaws.com/hellodeveloper
인증 성공시에 아래처럼 Login Succeeded 메세지가 출력된다.
2. 도커 이미지에 태그 지정
아래 명령어로 빌드한 Docker 이미지에 태그를 지정해준다.
docker tag <docker 이미지명> <ECR URI>
3. 도커 이미지를 ECR에 푸쉬하기
아래 명령어로 ECR에 빌드 및 태그를 지정한 이미지를 푸쉬하면 된다.
docker push <ECR URI>
중간에 layer already exist가 뜨는 이유는 기존에 내가 푸쉬했던 이력이 있어서 그렇디. 처음 푸쉬한다면 모두 Pushed로 메세지가 출력된다.
● AWS ECR에 업로드된 이미지를 EC2로 가져오기
우선 EC2에 awscli, docker 등을 설치해줘야 한다.
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html
1. 사용자 프로필 추가하기
이전 게시글을 참고해서 awscli를 통해 사용자를 추가해준다. 명령어는 아래와 같다.
aws configure --profile <IAM 사용자명>
ex) aws configure --profile dongwoo
2. ECR 로그인하기
aws ecr get-login-password --profile <IAM 유저명> --region <region> | docker login --username AWS --password-stdin <ECR URI>
3. ECR에 업로드한 이미지를 받아오기
docker pull 명령어를 사용해서 기존 ECR에 업로드한 이미지를 다운로드 할 수 있다.
sudo docker pull <ECR URI>
자동으로 가장 마지막 이미지를 pull 하게된다.
● 가져온 이미지를 EC2에서 실행하기
sudo dokcer images 명령어로 위에서 가져온 이미지를 확인해본다.
docker run 명령어를 사용해서 프로젝트를 배포해본다.
우선 나의 경우 환경변수 파일을 ~/root/.env 경로에 임시로 만들어뒀다. 추후 파라미터 스토어에서 관리할 예정이다.
추가로 터미널을 종료해도 백그라운드에서 실행될 수 있도록 -d 옵션을 사용해준다.
docker run -d --env-file <환경변수파일 경로> -p <포트번호> <docker 이미지명>
ex) docker run -d --env-file ~/root/.env -p 5000:5000 <docker 이미지명>
docker ps 명령어를 사용해서 현재 실행중인 컨테이너 확인이 가능하다.
● 배포된 어플리케이션을 접속해보기
우선 보안그룹 - 인바운드규칙에서 어플리케이션을 실행할 포트를 허용해줘야한다.
nestjs에서 아래처럼 테스트용 엔드포인트를 작성해두었다.
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get('/ping')
ping() {
return 'ping';
}
}
이제 접속해보자