# 15. AWS와 GCP로 배포하기

## 15.AWS와 GCP로 배포하기

배포를 위한 준비사항... 9장 NodeBird 예제

### 15.1 서비스 운영을 위한 패키지

*   morgan, express-session 미들웨어중 개발옵션 -> **배포용으로 설정**

    ```javascript
    // app.js
    ...
    // morgan
    if(process.env.NODE_ENV === 'production') { // .env는 정적파일이므로, cross-env 로 설정해야함
      app.use(morgan('combined'));  // 운영환경 : combined 모드
    } else {  
      app.use(morgan('dev'));       // 개발환경 : dev 모드
    }
    ...

    // express-session
    const sessionOption = {
      cookie : {
        httpOnly: true,
        secure : false // -> true : https 적용 or 로드밸런싱 등을 위해
      }
    }

    if(process.env.NODE_ENV === 'production'){
      sessionOption.proxy = true; // https 적용을 위해 노드서버 앞에 다른 서버를 두었을때
    }
    ```
*   sequelize 배포시, 비밀번호가 하드코딩되는 경우 문제가 됨\
    config.json -> config.js파일로 생성하여 적용 가능\
    js파일이므로 dotenv 모듈을 사용 가능. 나머지정도들도 변경하는 것이 좋음

    ```javascript
    module.exports = {
      development : {
        username : 'root',
        password : process.env.SEQUELIZE_PASSWORD, // 하드코딩된 정보를 env 파일을 통해 할당
        /*...*/
      },
      procuction : {
        /*...*/
        logging : false // -> sql 출력을 숨김.
      }
    }
    ```
*   cross-env **동적으로 process.env 변경**

    ```javascript
    {
      "scripts: {
        "start": "cross-env NODE_ENV=prodction PORT=80 node app",
        "dev": "nodemon app"
      }
    }
    ```
*   retire 설치된 패키지에 문제가 없는지 확인

    ```bash
    # 설치
    $ npm i -g retire
    # 실행 -> 문제가 있으면 콘솔에 내용 출력
    $ retire

    # npm i 할때 자동으로 취약점을 검사
    $ npm audit
    ```
*   pm2 원활한 서버 운영을 위한 패키지\
    개발 : nodemon, 운영 : pm2 를 쓴다는 말이 있을 정도...\
    1\. 서버가 에러로 다운 -> 서버를 다시 시작 시켜줌\
    2\. 멀피프로세싱 가능.. 멀티스레드 아님,

    ```bash
    # 설치
    $ npm i -g pm2 && npm i pm2

    {
     "start" : "cross-env NODE_NEW=production PORT 80 start app.js",
     "dev" : "nodemon app"
    }

    # 사용
    $ pm2 list        # 노드프로세스 확인
    $ pm2 kill        # 종료
    $ pm2 reload all  # 재시작
    $ pm2 start app.js -i -1 # 디폴트는 0 (프로세스 생성을 현재 코어수 만큼), -1 : 현재코어 - 1개 사용
    $ pms monit       # 현재 프로세스 모니터링
    ```
*   **winston** 운영에서, console.log, console.error 대채하기 위한 모듈 에러발생시, 로그는 사라질 수 있다... 로그 -> 파일저장 하기 위한 용도

    ```javascript
    const {createLogger, format, transports} = require('winston');

    const logger = createLogger({
      level: 'info',
      format: format.json(),
      transports:[
        new transports.File({filename: 'combined.log'}),
        new transports.File({filename: 'error.log', level: 'error'})
      ]
    })
    ...
    logger.add(new transports.Console({format: format.simple()}));
    module.exports = logger;
    ```

    **level** : 로그의 레벨. error > warn > info > verbose > debug > silly\
    **format** : 로그의 형식. json, label, timestamp, printf, simple, combine **transports** : 로그저장방식. new transports.File, new transports.Console .. 다양한 방식 혼합 사용 가능
* helmet, hpp 서버의 각종 **취약점을 보완**해주는 패키지 app.use 미들웨어 설정해서 사용하면 됨
*   connect-redis 멀티 프로세스 간 세션 공유를 위해 `레디스`와 `익스프레스`를 연결 해주는 패키지.\
    세션아이디와 실제 사용자 정보가 `메모리에 저장` 됨. -> 서버다운 ? 로그인이 다 풀려버림.\
    -> `데이터베이스에 저장 필요` 이때 사용되는 것이 `레디스`\
    -> 레디스 데베 설치도 필요... [http://redislabs.com](http://redislabs.com)

    ```
    # .env
    REDIS_HOST=redis-11196.c44.us-east-1-2.ec2.cloud.redislabs.com
    REDIS_PORT=11196
    REDIS_PASSWORD=adadakldsakldasl?
    ```

    ```javascript
    // app.js
    ...
    const session = require('express-session');
    const RedisStore = require('connect-redis')(session);
    const sessionOption = {
      ...
      store: new RedisStore({
        host: process.env.REDIS_HOST,
        port: process.env.REDIS_PORT,
        pass: process.env.REDIS_SECRET,
        logErrors: true // redis 에러 발생시 콘솔 출력여부
      })
    }
    ```
*   nvm, n node 버전 업데이트.\
    윈도우 -> `nvm-installer`\
    linux, max -> `n`

    ```bash
    # linux, mac -> n
    # 노드 설치 버전 확인
    $ nvm list

    # 설치
    $ nvm install [버전]
    $ nvm install latest

    # 사용
    $ nvm use 10.1.0
    $ node -v
    ```

### 15.2 Git과 GitHub 사용하기

설치 및 생략

```bash
# git remote add [별명] [주소]
$ git remote add origin https://~~

# 잘못입력했을 때 : git remote rm 별명
$ git remote rm origin

# push : git push 별명 브랜치
$ git push origin master
```

### 15.3 AWS 시작하기

가입해야해서 일단 생략

1. 인스턴스 생성
2. 리전선택&#x20;
3. 블루프린트 노드 선택 (리눅스)
4. NodeJS 앱 선택
5. 인스턴스 계획 선택, 프리, 5달러...

### 15.4 AWS 배포하기

1. SSH 사용하여 연결 -> VM 인스턴스 접속 가능
2. vm에 MySQL 설치 (서버 분리를 권장)
3. git 에서 소스 clone
4.  Lightsail 기본적으로 아파치 서버가 켜져있는데.. 노드랑 동시실행이 불가 -> 종료 필요

    ```bash
    $ cd /opt/bitnami
    $ sudo ./ctlscript.sh stop apache
    ```
5.  소스 다운 받은 곳으로 이동하여 패키지 설치

    ```bash
    $ cd ~/node-deploy
    $ npm i
    $ sudo npm i -g pm2 cross-env sequelize-cli
    $ sequelize db:create --env production
    $ sudo npm start
    ```
6. 퍼블릭 아이피 -> [http://퍼블릭IP로](http://xn--ip-qj9im7b84koo1b) 접근 하여 확인하기, **https는 접속안됨** -> 도메인 구입 및 인증서 발급등의 별도 설정 필요

### 15.5 GCP 시작하기

AWS랑 UI만좀 다르고 동일 http, https 옵션체크 -> 트래픽 허용

### 15.6 GCP 배포하기

마찬가지 책참고로 마무리 GCP Cloud SQL -> MySQL 전용 서비스 , AWS RDS 비슷한 맥락
