TIL | WIL

3/22 수 (HTTPS로 배포하기 사전 조사 및 과정) TIL, TIT

깊은바다거북 2023. 4. 12. 23:35

(최종 프로젝트 진행중)

오늘은 서버 배포를 진행하였다.


※ 이하는 스스로 공부하며 적어둔 노트이며 불확실한 내용이 있을 수 있습니다. 학습용으로 적합하지 않음을 유념해주세요. ※

Heroku로 배포를 결정하기까지 의사 결정 과정

로컬 컴퓨터에서 만든 웹 서비스를 빌드하여(정적 파일로 만든 다음에) S3에 배포할 수 있다고 한다.

  • 빌드(Build)란?

    소스 코드 파일을 컴퓨터에서 실행할 수 있는 독립적인 형태로 변환하는 과정과 그 결과를 말한다.

    인간이 짠 코드를 한 번에 기계어로 변환해주는 작업을 컴파일이라고 하는데, 빌드는 이렇게 컴파일 된 코드를 실제 실행할 수 있는 상태로 만드는 일. (빌드 과정을 도와주는 도구를 Build Tool이라고 함)

    정리:

    Build = Complie + 그 외 작업 (테스팅(testing)과 배포(distribution) 등)

    Run = Build + 실행

    = (Complie + 그외작업) + 실행

    (참고: https://choseongho93.tistory.com/296#:~:text=서버에 반영을 하는,을 "빌드"라고 합니다.&text=빌드(Build)란%3F,과 그 결과를 말합니다.)

    현업에서는 두 가지 의미로 build라는 단어를 사용하는 듯 한데,

    1. Compile -> Deploy의 두 단계를 합친 것을 Build라고 하기도 하고
    1. Compile -> Build -> Deploy 중 가운데 단계를 Build라고 부르기도 한다.

  • 빌드를 할 때 "build": "cross-env=production nest build" 아니면 cross-env NODE_ENV=production,?

    "heroku-postbuild": "ng build --prod" 여기다 cross-env=production 덧붙이기?

    procfile 도 설정해서 푸시해줘야 한다.,,, (여기 참조: Deploy NestJS with Docker, Heroku, and GitHub Actions)

  • 빌드를 하면 정적 파일이 되는 것인가? 넵
  • 그러면 정적 호스팅 클라우드 서비스(?)인 S3나 Heroku에 올려도 되는 것인가? 넵

    ⇒ 다만 Heroku나 S3에서 후처리를 해줘야 한다. (Heroku - RDS 연결하기: https://devcenter.heroku.com/articles/amazon-rds)

  • 동적이라는 것은 백엔드단에서 다른 DB와 통신하거나 인증하는 등의 일을 말한다고 하는데, (그리고 라우팅?) 이게 들어가면 왜 S3에서는 동작하지 않게 되는 것인가?

    ⇒ S3 버켓과 DB 서버를 연동시켜주면 S3에 빌드 파일을 올려도 잘 동작하게 할 수 있다.,,, ⇒ EC2 하나를 일단 써야 S3로 디플로이할 수 있다고… RDS를 쓰기 위해서는! 백 용으로는. 프론트는 S3 버켓 하나로 배포가능한 것이 맞다.

  • 그래서 Heroku로 혹시 배포해보셨나요..? PHP 어플리케이션으로 위장하여 배포한다는데 저희 Nest.js 프로젝트를 배포할 때 문제가 없을까요? 넵 Node.js로 선택해주면 된다고.
  • Heroku로 배포하면 기본이 HTTPS 도메인이다.
  • Heroku로 배포하자..!

Heroku로 배포하기

(대부분 이곳을 참고하여: https://doiler.tistory.com/13)

  1. “start”: “nest start” ⇒ “start”: “node dist/main.js”로 수정함
    // package.json
    “start”: “node dist/main.js”

    빌드가 완료가 되면 heroku 쪽에서 서버를 실행 시켜야 하기 때문에 서버 실행 명령어에 빌드된 파일의 실행파일 경로를 적어줘야 한다고 한다.

    이제부터는 로컬 환경에서 실행할 때 npm run start을 실행하면 서버가 제대로 안 열리게 된다. 잊지 말고 npm run start:dev를 사용해줄 것.

  1. Heroku에 회원 가입 후 Heroku CLI 설치 완료함

    설치 후 전역변수 설정을 제대로 해줬는데, 프로젝트의 루트 폴더로 들어가면 “heroku --version”같은 heroku 명령어가 인식되지 않는 문제가 있었다. 일단 완전 시스템 루트 폴더 (cmd 창 처음 켜면 지정되는 경로)에서 이후 단계를 진행하였다.

  1. $ heroku login 을 명령하면 브라우저로 이동하게 되는데 여기서 로그인 진행 (이후로 Heroku 홈페이지에서 계속 진행함)

    ⇒ 뭔가 QR 코드 주고 인증하라는데, AWS 로그인 할 때 사용하는 Google OTP 모바일 앱으로 등록해서 사용 가능했다!

  1. $ heroku create 명령어로 생성하려니 카드 등록으로 본인인증을 해야 한다 그래서 등록함.

    https://mooin-cat.herokuapp.com/https://git.heroku.com/mooin-cat.git 주소를 얻음.

    (2022년 11월 28일부터 free-dyno정책이 폐지되었다고 한다. 지금 basic-plan으로 돌리는 중)

  1. deploy 탭에서 깃허브와 연동해주고 (깃헙 레파지토리 소유자의 공유 허락이 필요하다)

  1. settings 탭에서 하라는 대로 빌드 팩 2개 차례로 등록해줌.

  1. settings 탭에서 add config vars에 “PROJECT_PATH: ‘/’” 키-밸류 쌍을 등록해준다. (중요)

  1. settings 탭에서 add config vars에 .env 파일에서 쓰던 환경 변수를 전부 등록해준다.

  1. deploy 탭에서 Deploy a GitHub branch “main”을 deploy 버튼을 눌러 배포해준다.

    (자동 배포 체크도 가능하다: )

  1. 이렇게 deploy 버튼을 누르면 build 작업에 들어가게 되는데 여기서 계속 실패가 떠서 튜터님과 함께 트러블 슈팅을 진행하였다. (과정생략)

  1. 어쨌든 이후 AWS RDS 데이터베이스 서버까지 연결에 성공하여 잘 사용중.
    • 스크린샷(참고용)

      어떻게 해결했나:

      처음부터 계속 똑같이 이런 에러가 떠서 위의 여러가지 방법을 시도해 본 것이었다.

      두 번째 에러 메세지. 이것과 마지막 에러 메세지의 시간 로그를 보면 얼마나 붙잡고 있었는지 알 수 있다…
      감격의 마지막 에러 메세지. 도메인으로 접속해둔 페이지가 스스로 새로고침되려고 로딩중임을 알았을 때 손이 다 떨렸다. 이전까지는 매번 수동으로 새로고침 했었고 매번 에러가 떳었다.

      typeOrmConfig에서 host, port, username, password, dbname 이렇게 다 따로 떨어져 있던 것 대신, DATABASE_URL이라고 하나로 설정해서 넣어주니 되었다.

      // src/config/typeorm.config.service.ts
      @Injectable()
      export class TypeOrmConfigService implements TypeOrmOptionsFactory {
        constructor(private readonly conigService: ConfigService) {}
        createTypeOrmOptions(): TypeOrmModuleOptions {
          return {
            type: 'mysql',
            // host: this.conigService.get<string>('DATABASE_HOST'),
            // port: this.conigService.get<number>('DATABASE_PORT'),
            // username: this.conigService.get<string>('DATABASE_USERNAME'),
            // password: this.conigService.get<string>('DATABASE_PASSWORD'),
            // database: this.conigService.get<string>('DATABASE_NAME'),
            url: this.conigService.get<string>('DATABASE_URL'),
            entities: [
              User,
              Cat,
      				...
      			
      • 그렇담 Heroku에 따로 환경변수로 잡아준 건 없애도 작동하게 되는 건가?
      • dev 버전이랑 production 버전이랑 어떻게 가르지?

Heroku는 무료인가?

카드 등록까지 마친 ‘personal’사용자는 한 달에 1000 free dyno hours를 쓸 수 있다고 한다. ‘web’ 앱 하나 하나가 dyno hours를 사용한다.

https://help.heroku.com/8E2A2AIU/how-do-free-dyno-hours-work#:~:text=Personal accounts are given a,of 1000 hours per month

아닛, 2022년 11월 28일부터 더이상 아니라고 한다 (https://devcenter.heroku.com/articles/free-dyno-hours)

그래서 지금 $1.82 청구되고 있음. 1시간당 $0.01라고… 하면 지금 182시간 이상 사용 중이라는 것?


배포 (세미)완료

Heroku
https://dashboard.heroku.com/apps/mooin-cat/deploy/github

배포 도메인주소

https://mooin-cat.herokuapp.com

카카오 developers 내 애플리케이션에 이렇게 도메인 등록도 해줬다 (kakao map api 사용을 위함)(잘 됨 확인함)

Heroku 에러 로그 최신 것 하나 확인할 때 썼던 명령어: (프로젝트 디렉토리 말고 /USER>에서) heroku git:remote -a mooin-cat

Heroku 설정 파일 (어떤 환경 변수가 등록되어 있나) 확인하는 명령어: heroku config -a mooin-cat


Heroku는 Paas다

PaaS

: Platform as a Service

: 클라우드에서 제공되는 완전한 개발 및 배포 환경.

: 개발적으로는 서버, 저장소, 네트워킹, 미들웨어, 개발도구, BI, 서비스, 데이터베이스 , 빌드, 테스트, 배포, 관리, 업데이트 등 모든 어플리케이션 수명 주기를 지원하는 서비스.

: 앱개발자는 소스 코드만 등록을 하고 클라우드에서 모든것을 알아서 처리해주는 서비스. 대표적으로 Heroku가 있다.

Iaas

: Intrstructure as a Service

아마존 AWS의 EC2 / S3 + CloudFront, 구글의 GCP

Faas

: Function as a Service


아마존 AWS 이용해 HTTPS로 배포하려면

순서

  1. HTTPS를 적용할 도메인 구입하기. Route53에서 구매시 네임서버는 자동으로 등록됨.
  1. ACM으로 SSL인증서 등록하기
    1. 콘솔 → certificate manager
    1. CloudFront가 N.Virginia만 지원하니까 이걸 선택해줘야 한다고 한다. (왜 CloudFront를 사용하지? )
    1. Provision certificates 선택
    1. 공인인증서용 public certificate 선택, 도메인 입력해주기.
    1. select validation method에서 DNS 검증 선택
    1. 제공받은 값을 Route53에 등록한다.
    1. 인증서 발급 완료!
  1. CloudFront를 이용해 HTTPS를 적용하기.
    1. 콘솔 → CloudFront
    1. create distribution 클릭
    1. 버킷 endpoint 지정. …?
    1. 허용할 HTTP 메소드를 체크 및 rediract HTTP to HTTPS옵션도 체크.
    1. ACM에서 받은 SSL인증서를 등록.
    1. 정상 작동 확인하기. CloudFront에서 ‘Enabled’되었나.
  1. Route53에서 www.domain.com과 domain.com에 대한 DNS를 등록해주기. (www를 쓴 유저와 그렇지 않은 유저 모두 제대로 접근이 가능하도록)
  • AWS의 서비스 (EC2, S3, Cloud Front)명 정리
    • S3: Simple Storage Service. 온라인 스토리지 웹 서비스. 파일 서버 역할.

      객체 < 버킷

      정적인 html이나 이미지 등을 제공하는데 용이해서 …

      HTTP 프로토콜로 파일에 접근 가능. SSL 인증서 적용은 불가능(=HTTPS 프로토콜 사용이 불가능)

    • EC2: Elastic Compute Cloud. 가상 컴퓨터 머신. 웹 서버 구축에 사용.

    • Cloud Front: AWS에서 제공하는 CDN 서비스.

      SSL 인증서를 이용한 HTTPS 호스팅을 지원함.

      원본 데이터를 갖는 서버인 Origin(S3나 EC2 인스턴스)과, 캐시 기능을 제공하는 중계 서버인 Edge Location 서버들로 나뉨.


Uploaded by N2T