TodoList - 배포하기

송현섭 ·2024년 1월 10일

백엔드

목록 보기
8/15

DB(데이터베이스) 배포


+a) MongoDB atlas 란?

  • MongoDB에서는 아틀라스(Atlas)로 클라우드에 데이터베이스를 설정

  • 아틀라스 = GUI와 CLI로 데이터를 시각화, 분석, 내보내기, 그리고 빌드하는 데에 사용, 완전 관리형 클라우드 데이터베이스 서비스

  • 아틀라스 사용자는 클러스터를 배포 할 수 있으며, 클러스터는 그룹화된 서버에 데이터를 저장

  • 클러스터 = 인스턴스들의 모임(데이터를 저장하는 서버 그룹)으로, 여러 대의 컴퓨터를 네트워크를 통해 연결하여 하나의 단일 컴퓨터처럼 작동, 이 클러스터는 데이터를 저장하고 관리하기 위해 함께 작동하는 여러 서버(인스턴스)로 구성

  • atlas를 사용하면 로컬 시스템이나 연결한 MongoDB 서버에 저장되지 않고 MongoDB Atlas 클러스터에 저장됨






  • Create 버튼 클릭






  • FREE 를 선택하고 Provider 를 AWS로 선택

  • MongoDB 에서는 Storage 용량을 512MB 까지는 무료로 제공






  • Cluster0 이란 이름으로 Cluster가 생성됨

  • Connect 버튼 클릭






  • 데이터 관리 Tool 로 Compass 선택






  • 다음으로 Compass 관련 설정 후 주소를 복사 (DB 주소)






  • 해당 주소를 Compass 연결주소에 입력하고 Connect하면 이제 Compass에서 Cluster의 DB 주소로 연결됨






  • 이후 .env 파일로 가서 주소에 대한 변수값 지정

  • <password> 부분에 아까 설정한 비밀번호 입력

  • 뒤에 붙은 todoList 는 생성될 database 이름







백엔드 서버 배포


  • 백엔드 프로젝트 폴더 루트의 package.json 파일 내에 script 내부에 위와 같이 작성
    AWS 는 node로 실행하는 것으로 인식하기 때문에 nodemon이 아닌 node로 입력해줘야함!






  • 다음으로 프로젝트 폴더 내의 최상위에 .ebextensions 폴더를 만든 후 내부에 cors.config 파일 생성






  • 이후 위와 같이 optionSetting 을 해줌
    Beanstalk 정적파일 제공 Docs

  • 위의 경우 option 설정을 해석해보면, /api 로 시작하는 경로로 들어오는 모든 요청에 대해 localhost:3000 으로 해당 요청을 proxy하겠다는 의미

  • 본래 이 세팅방식은 특정 요청(ex. /static)에 대해 Beanstalk에 올린 프로젝트 내의 지정한 임의경로에서 정적파일들을 찾아서 모아오기 위한 것
    -이 설정을 통해서 실제 배포 후 정적파일(js,css..)들이 정상적으로 받아와짐
    -정적 파일을 가져오는 방식 중의 하나로 AWS에서는 이 방식 보다는 S3에서 따로 가져오는 방식을 권장

  • 여기서는 개발환경에서 배포가 정상적으로 진행되었는지 테스트하기 위해 들어오는 요청을 프론트 서버로 proxy하게 설정함




+a) .ebextensions

  • 기본적으로 Beanstalk는 배포 관련 복잡한 설정들을 자동으로 해주기에 편리한 장점이 있지만 그에 따라 세부조정과 설정에 한계가 있음

  • 이 점을 보완하기 위해 AWS에서 제공한 방식이 Config 형식의 파일에 작성한 문법으로 설정부분을 보완해 줄 수 있게 한 ebextensions

  • 프로젝트 최상위 경로에 .ebextensions 폴더를 생성하고 해당 폴더 안에 config 확장자 파일을 생성하여 내부에 수행목록을 작성하면 배포에 사용할 aws 리소스를 지정할 수 있으며 배포 중 사용할 명령어와 환경변수등을 설정할 수 있음
    ebextensions Docs

  • config 확장자 내에 작성할 때는 json 형식이나 yaml 형식으로 작성해야 함
    환경변수 설정, 로드밸런서 설정 등 다양한 기능을 제공하는데 Beanstalk 자체를 처음 쓰다 보니 이해가 잘 안됨. 배포를 해보면서 필요한 부분이 있을 때마다 문서를 읽어보면서 공부할 필요가 있을듯 함







  • 다음으로 Beanstalk에 올릴 프로젝트 폴더를 압축함
    이 때 반드시 zip 확장자로 압축해야 하며 압축을 풀었을 때 디렉토리 내 목록에 package.json이 존재해야 함

  • 이렇게 원시적인 압축 방식 외에도 터미널에 EB용 커맨드 명령어 tool을 설치해서 해당 명령어로 폴더 관리하는 방법도 있음!







Elastic Beanstalk 환경(environment) 설정

  • AWS 로그인 후 Elastic Beanstalk 페이지로 이동







  • 왼쪽 사이드 바에서 환경 탭 클릭







  • 환경 생성 버튼 클릭해서 새로운 environment 생성







  • 웹 서버 환경으로 설정 후 사용할 앱 이름 설정







  • 사용할 도메인 이름 (해당 주소가 곧 백엔드 서버 주소가 됨)을 지정하고 가용성 체크







  • 사용하는 플랫폼 선택 (여기서는 node.js 18.xx 버전 사용)







  • 앱 코드는 업로드 방식을 선택하고, 버전 레이블 작성
    배포도 수정하고 업데이트 할 때마다 재배포가 진행될 텐데 그에 맞게 버전관리가 가능하도록 버전 레이블을 작성해 줌 (필수값)

  • 업로드 방식을 로컬파일로 선택 후 앞서 압축했던 zip파일을 올려 줌







문제 발생! - role이 존재하지 않음

  • 이후 service-role 과 ec2-role 을 설정해서 AWS의 각 리소스에 대한 권한을 부여받아야 하는데 문제가 발생함

  • 일종의 버그인지 role을 선택하려 해도 보이지 않음

  • 해결방안 을 토대로 role을 불러올 수 있었음






  • 다음으로 인스턴스 구성 항목에서 EC2 보안그룹에 모든 그룹을 체크
    EC2 보안그룹 = EC2 보안 그룹은 특정 인스턴스 또는 그룹의 트래픽을 제어하는 규칙의 집합으로, 이를 통해 어떤 종류의 트래픽이 특정 인스턴스로 들어오거나 나가도록 허용 또는 거부할지를 설정 (일종의 방화벽 역할)






  • 그리고 인스턴스 유형에서 t3.small 을 제거해 줌

  • t3.micro 는 기본 무료버전 인스턴스로 여기서는 무료버전만 사용할 것임






  • 이후 .env에 저장했던 환경변수들을 aws 콘솔에서 지정

  • AWS는 프로젝트 내의 .env 를 읽어서 코드 인식을 하지 않기 때문에 임의로 지정해줘야 함






이후 검토과정을 보고 제출을 클릭






  • 대략 5분정도 기다리면 환경설정이 완료됨








문제 발생! - package.json을 찾을 수 없습니다

  • 이후 지정된 도메인 주소로 접속을 해 보았는데 페이지가 로드되지 않는 오류가 발생함

  • 보통 페이지 로드 오류라면 http 상태코드라도 전달될 텐데 아예 요청 헤더정보도 없고, 아무것도 없음




  • 해당 환경의 상세 탭에서 로그 요청을 한 다음 해당 로그 기록을 다운받아서 에러를 체크






해결방안

[ERROR] An error occurred during execution of command [app-deploy] - [check Procfile]. Stop running the command. Error: node.js may have issues starting. Please provide a package.json file or add server.js/app.js file in source bundle
  • 발견한 에러의 내용은 배포과정에서 Procfile 이 없고, package.json, app.js 가 없다고 함

  • Procfile 관련 에러는 선택적 사항이라 해당 파일을 생성하는 대신에 package.json 내에 script 에 node 실행 명령어 추가했기 때문에 PASS!

  • 문제는 올려 둔 소스 내부에 package.json 파일을 찾지 못하는 것이었는데 알고 보니 프로젝트 폴더를 압축할 때 각 파일들이 있는 것을 묶어서 압축해야 했는데, 그것들을 담고 있는 상위폴더 자체를 압축해서 인식하지 못하는 것이었음








502 Bad Gateway 에러

  • 정상적으로 에러 핸들링을 하고 났더니 이번에는 502 에러가 발생



[error] 2701#2701: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 49.168.7.211, server: , request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "todo-backend.ap-northeast-2.elasticbeanstalk.com"
  • 요청을 하는 url의 포트번호는 8080임

  • 그러나 현재 구현된 백엔드 서버는 포트번호를 5000번으로 받고 있음

  • 양 쪽의 포트번호가 다르기 때문에 (문이 다름) Bad Gateway 에러가 발생했던 것






  • AWS 환경에 PORT 8080 넣어주고 서버측에는 위와 같이 8080포트도 감지하도록 설정

  • 이후로는 8080 번호, 또는 5000 포트번호를 감지하게 됨
    정확히는 env.PORT는 AWS 환경에서만 존재하기에 서버 측 코드에 존재하지 않음. 따라서 AWS 쪽에서 오는 요청은 env.PORT로 받게 되고, 일반 로컬환경에서 오는 요청은 env.PORT 가 정의되어 있지 않기에 5000번으로 받게 됨








  • 에러 핸들링 과정에서 코드가 수정되었기 때문에 배포과정도 다시 진행되어야 함

  • 똑같은 방식으로 새로 프로젝트를 압축한 다음, 환경 상세 탭에서 업로드 및 배포 를 클릭하여 재배포 진행







에러 발생! - mongoDB 연결 에러

  • 이젠 정상 동작할 줄 알았으나 이번에는 응답으로 자꾸 status 400을 보냄

  • catch 블록에 걸렸다는 소리인데 받은 응답값에 error 객체는 빈 객체를 반환

  • 로그를 확인할 필요를 느껴 다시 최근 로그를 뜯어 봄







MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you're trying to access the database from an IP that isn't whitelisted
  • 로그를 살펴보니 mongoDB 연결이 제대로 안 되고 있었음

  • 1시간 가량 삽질하고 나서 .env 내에 환경변수로 설정된 DB 주소의 DB 이름과 실제 생성되어 있는 DB 이름이 다르다는 것을 확인

  • 이름값을 통일시켜주니 status: ok 와 함께 정상적으로 동작





+a) 기존의 로컬환경에서 사용하던 몽고DB와 atlas로 생성한 클러스터 기반 DB의 차이

  • 이후로 데이터 로그를 확인해 보려는데 자꾸 빈 배열을 반환하는 것에 의문을 느끼다 로컬에서 클라우드 환경으로 넘어가면서 DB 주소를 바꿨던 것을 인지함

  • 기존 로컬 환경 DB 서버에는 연습 겸 데이터가 저장되어 있었으나 새로 만든 클라우드 환경 공용 DB 서버는 비어 있기에 빈 배열만 반환했던 것

    Compass 주소 연결 후 사용할 시 어떤 DB인지 헷갈리지 않도록 주의!

profile
막 발걸음을 뗀 신입

0개의 댓글