AWS 프로비저닝을 통한 증권 서비스 구축 02

이상훈
상훈 Devlog
Published in
9 min readJun 16, 2024

개요

1. 증권 서비스 shdart 프로젝트 개발

2. AWS 프로비저닝을 통한 증권 서비스 구축 01

3. AWS 프로비저닝을 통한 증권 서비스 구축 02

도커와 도커 컴포즈를 이용하여 개발 프로젝트의 도커라이징과 ECR 프로비저닝을 진행합니다. 구축해볼 전체 아키텍처는 아래와 같습니다.

개발자는 증권 프로젝트를 도커라이징하고 ECR 프라이빗 레포지토리에 배포합니다. ECS 작업 정의에서 배포한 이미지를 설정하고 서비스를 통해 컨테이너를 실행시킵니다. 최종적으로 사용자가 http 요청을하면 서비스와 연결된 로드밸런서를 통해 해당 컨테이너 인스턴스에 접속하게 됩니다. 이 일련의 과정을 자세히 알아보겠습니다.

도커라이징

ECR 프로비저닝을 위해 가장 먼저 현재 개발된 프로젝트를 도커라이징해야 합니다. 프로젝트는 다음과 같이 구성되어 있습니다.

  • sh-dart_web: Angular 프론트엔드 프로젝트
  • sh-dart: NestJS 백엔드 프로젝트
  • nginx: 웹서버

최종적으로 다음과 같은 구조로 구성합니다.

프론트엔드 및 웹서버

sh-dart_web 프론트엔드 루트 경로에 nginx.conf를 다음과 같이 작성 후 추가합니다.

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 80;
location / {
root /etc/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass <http://nestjs-app:3000>;
proxy_http_version 1.1;
}
location /auth/ {
proxy_pass <http://nestjs-app:3000>;
proxy_http_version 1.1;
}
location /socket.io/ {
proxy_pass <http://nestjs-app:3000>;
proxy_http_version 1.1;
}
}
}
  • index.html 설정: 80포트를 사용하게 되고 try_files $uri $uri/ /index.html; 설정을 통해 SPA 앱 특성 상 모든 절대 경로에 index.html을 띄우게 합니다.
  • 리버스 프록시 설정: /api, /auth, /socker.io 등 백엔드 서비스 3000번 포트로 리버스 프록시를 합니다. (proxy_passnestjs-app명명은 추후 백엔드 도커라이징 시 설정하게 됩니다.)

다음으로 루트 경로에 dockerfile을 다음과 같이 작성 후 추가합니다.

# Step 1: Angular 프로젝트 빌드
FROM node:18 AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build:prod

# Step 2: Nginx를 통한 Angular 앱 서빙
FROM nginx:latest
COPY --from=build dist /etc/nginx/html
COPY --from=build dist/assets /etc/nginx/html/assets
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  • Angular 프로젝트 빌드: Node.js 18 버전 기반으로 구축하며 NPM 의존성 설치와 프로젝트 빌드를 합니다.
  • Nginx 빌드: Angular 프로젝트에서 빌드한 번들 파일과 이미지 파일을 nginx 서빙 경로에 복사하고 80 포트로 실행합니다.

백엔드

sh-dart 프로젝트 루트 경로에 dockerfile을 다음과 같이 작성 후 추가합니다.

FROM node:18
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/main"]
  • Node.js 18 버전 기반으로 구축하며 NPM 의존성 설치와 프로젝트 빌드를 합니다.
  • 3000번 포트로 실행하게 됩니다.

도커 컴포즈

도커 컴포즈란 여러 개의 도커 컨테이너들을 하나의 서비스로 정의하고 묶어서 하나로 관리할 수 있는 도구입니다.

가장 상위 루트 경로에 docker-compose.yml을 다음과 같이 작성 후 추가합니다.

services:
angular:
build:
context: ./sh-dart_web
dockerfile: dockerfile
container_name: angular-app
ports:
- "80:80"
depends_on:
- nestjs

nestjs:
build:
context: ./sh-dart
dockerfile: dockerfile
container_name: nestjs-app
ports:
- "3000:3000"
  • 프론트엔드: context에 프로젝트 경로를 지정합니다. 이때 이름은 angular-app으로 하고 호스트 80 포트를 컨테이너 80포트로 포트 포워딩 설정을 합니다. depends_on: nestjs 설정을 통해 nestjs가 실행한 후 종속적으로 실행할 수 있도록 합니다.
  • 백엔드: 마찬가지로 context로 프로젝트 경로를 실행하고 3000포트로 포트포워딩 설정을 합니다.

최상위 경로에서 도커 컴포즈 빌드 명령을 다음과 같이 실행합니다.

docker compose up --build

컨테이너 이미지가 다음과 같이 생성된 것을 확인 할 수 있습니다.

ECR 생성 및 이미지 등록

이제 AWS ECR에 빌드한 컨테이너 이미지를 등록해보겠습니다. 프론트엔드와 백엔드 2개의 프라이빗 레지스트리를 생성합니다.

AWS ECR에서 리포지토리 생성을 클릭합니다.

프라이빗을 선택 후 리포지토리 이름을 sh-dart로 설정하고 리포지토리 생성 버튼을 클릭합니다.

생성이 완료되면 리포지토리 URL을 복사해둡니다. 추후 ECR 작업 등록 시 사용하게 됩니다.

sh-dart 리포지토리 이름을 클릭하여 상세 페이지로 들어와 푸시 명령 보기를 클릭합니다.

다음 4가지 명령을 통해 로컬 환경에서 빌드했던 컨테이너 이미지를 푸시합니다.

  1. AWS CLI을 통해 docker 로그인을 합니다.
  2. 프로젝트를 빌드합니다. (이미 완료)
  3. 이미지에 태그를 지정합니다.
  4. 리포지토리로 푸시합니다.

동일하게 프론트엔드 이미지도 레지스트리 생성 후 푸시합니다. 추후 ECR에서 작업 정의서 생성 시 이 레포지토리의 URI가 사용됩니다.

ECS 작업 정의

AWS ECS 태스크 정의에서 에서 새 태스크 정의 생성을 클릭합니다.

태스크 정의 패밀리의 이름을 sh-dart로 설정합니다.

시작 유형은 서버리스 컴퓨팅을 위해 AWS Fargate를 선택합니다. 운영체제와 CPU, 메모리를 설정해줍니다. Fargate의 요금은 여기서 설정한 CPU와 메모리에 따라 달라지게 됩니다.

먼저 백엔드 컨테이너에 대한 정보를 입력해줍니다. 이때 이미지 URL은 ECR 프라이빗 레지스트리의 URI를 입력합니다.

컨테이너 추가 버튼을 클릭하여 프론트엔드 컨테이너에 대한 정보를 입력한 후 생성 버튼을 클릭합니다.

클러스터 및 서비스 생성

AWS ECS 클러스터로 이동하여 클러스터 생성을 클릭합니다.

클러스터 이름과 AWS Fargate를 설정하고 생성 버튼을 클릭합니다.

생성된 클러스터 상세페이지에서 서비스 생성 버튼을 클릭합니다.

시작 유형과 Fargate를 선택합니다.

애플리케이션 유형을 서비스로 선택 후 작업 패밀리를 선택합니다. 서비스 이름을 지정하고 원하는 태스크에 2로 입력하여 서비스 시작 시 태스크가 2개가 실행되도록 합니다.

다음으로 로드밸런서를 연결해줍니다. 이 때 컨테이너는 sh-dart_web 컨테이너의 nginx 80 포트를 연결합니다.

로드밸런서의 80 포트 요청을 수신할 리스너도 생성해줍니다. 대상 그룹은 클러스터의 작업들이 됩니다. 이 때 상태 확인을 위해 status 200을 응답 받는 프로토콜과 경로를 입력합니다. 마지막으로 생성 버튼을 클릭합니다.

이제 로드밸런서의 DNS로 접속하게 되면 최종적으로 증권 서비스에 접속할 수 있게 됩니다.

--

--

이상훈
상훈 Devlog

Frontend Developer 😁😁 #angular #javascript #typescript #scala #node