쪼렙 as! 풀스택

React-Next.js 프로젝트, AWS - Elastic Beanstalk 에 배포 삽질기. 본문

개발 일지/AWS

React-Next.js 프로젝트, AWS - Elastic Beanstalk 에 배포 삽질기.

코코앱 2018. 7. 30. 17:24

React + next.js 로 정말 신나게 코딩하면서, 프로젝트의 마무리 단계에 와있었다.


그동안은, 당연하게 localhost:3000 로 테스트를 하고 있었고,  서버 테스트는, next 를 만든 zeit 사의 'now' 서비스를 사용했었다.


zeit / now 서비스는 정말 감동적으로 좋은 서비스였다.

그냥 터미널에다 'now' 라고 3글자만 치면, 자동으로 프로젝트를 서버에 올리고, 자동으로 빌드되고, 곧장 실서버 상황을 볼 수 있었기 때문이다.


그러다가, 이제 정말 product 로 배포해야할 때가 다가 왔고, 그래서 진짜 실서버 테스트를 하려고, AWS - Elastic Beanstalk 에 올려보려고 했다.

나는 이제껏, BackEnd 는 다 PHP 로 개발 해 오다가, 이번에 React 로 프로젝트를 변경하면서, 이참에 서버도 Node.js 로 바꿔보았기 때문에 Node.js 는 완전 처음이라 할 수 있다.

PHP 서버는, 뭐, 빌드하고 뭐고 할것도 없고, 그냥 파일 올리면 곧장 배포가 시작되기 때문에 Elastic Beanstalk 로 배포하는데 매우 편리했었는데,


처음 다뤄보는 Node 서버를 Elastic Beanstalk 로 배포하려니 문제가 생겼다!!!!!!!



1. Next 프로젝트는 start 되기 전에 필수적으로 'next build' 과정이 필요하다!

- EB 에서 Node Command 를 설정할 수 있는 방법들이 여러가지 있다. (.ebextensions 사용하거나, EB 설정에 노드 커맨드가 있따.)

- Elastic Beanstalk 는 pakcage.json 에 있는 dependencies 를 자동으로 설치한 후, app.js, server.js, "npm start" 가 기본적으로 실행된다고 한다.

그래서 package.json 에 있는 script 를 빌드 후에 start 되도록 변경했다.

- package.json

"scripts": {
...
"start": "next build && NODE_ENV=production node server.js"
},


- 2018. 12. 5일 수정.

- 위에 방법도 몇번 문제가 생겼다. 배포할때 소스에서 node_module 을 제외하고 배포를 했었는데, 그러면 beanstalk 에서 알아서 package.json 에 dependency 에 있는 소스들을 설치하고 빌드까지 해주긴 했었다. 그런데, 그과정에서 오류가 생길때가 있더라. 아니면 문제없던 서버가, 중간에 다시한번 build 를 하면서 서버가 문제가 생기기도 하고.


- 그래서 그냥 배포하기 전에 일단 내가 직접 build 를 하고 /.next 폴더 와 /node_module 까지 포함한 모든 소스를 압축해서 배포를 했더니, 아직까지 아무 문제가 없다.


"scripts": {
...
"build": "next build",
"start": "NODE_ENV=production node server.js"
},




2. 이번에는 next 프로젝트를 Build 하는데 permission denied 가 시작되었다.

- 프로젝트의 루트에 .npmrc 파일을 추가한다.

- .npmrc


unsafe-perm=true



3. 프로젝트 루트에 .ebextensions  폴더를 만들고, 00_dir_permission.config 파일을 추가한다.

-/.ebextensions/00_dir_permission.config

files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/00_set_tmp_permissions.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
chown -R nodejs:nodejs /tmp




4. PORT 값을 변경해주자.

- 아무 생각없이 처음에 기본 셋팅되어있는 localhost:3000 포트를 계속 쓰고 있었는데, Elastic Beanstalk 의 NGINX 서버는 기본적으로, 80포트로 들어온 요청을, 8081 포트로 전달한댄다.

- 이 포트를 변경하고 싶으면 참고 :  https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/nodejs-platform-proxy.html 

- beanstalk 가 process.env.PORT 에 포트 값을 전달해 준다고 한다.


- server.js

const express = require('express')
const next = require('next')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const PORT = process.env.PORT || 8081

app.prepare()
.then(() => {
const server = express()

...

server.listen(PORT, (err) => {
if (err) throw err
console.log('> Ready on port ' + PORT)
})





5. nextjs + mobx 를 사용한다면, mobx 환경이, next 의 example 환경이랑 조금 달라진다.

-  babel-plugin-transform-class-properties, babel-plugin-transform-class-properties 파일이 devDependencies 에 정의되어있는데, 실제 빈스토크가 돌아갈 때, 빌드를 하지 못하더라.... 왜 그런지는 나도 모르겠다. 그냥 Dependencies 에 넣어준다.

- next가 6.x 버전으로 오면서 babel 버전을 7.x beta 를 사용하더라. babel 버전이 7일때, decorator-legacy 설정이 달라진다.


- package.json

"dependencies": {
"@babel/plugin-proposal-decorators": "^7.0.0-beta.55",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5"
}


- .babelrc

{
"presets": [
"next/babel"
],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
"transform-decorators-legacy",
"transform-class-properties"
]
}



Comments