기본 콘텐츠로 건너뛰기

nodejs (express) + mongodb in Heroku

nodejs (express) + mongodb in Heroku

nodejs (express) + mongodb in Heroku

전부터 알고 있던 cloud base 개발 환경인 heroku를 한번 사용해보기로 했습니다. 일단 nodejs로 만들어진 application 이고, express와 mongodb를 사용하고 있는데. 이와 같은 환경을 무료로 제공해주는 곳 중에서 가장 유명하고, 한번 써보고자 하는 욕구가 강한 서비스여서 접근해보기로 했습니다.

먼저, 배포할 application의 구성입니다.

nodejs

express

mongodb

google OAuth 이용

nodejs + mongodb application deploy

Heroku service 가입

email을 등록시켜주면, 가입신청 확인 mail이 날라옵니다. 클릭후, password 설정만 하면 완료됩니다.

완료 후, https://dashboard-next.heroku.com/ 에서 Management Account -> Billing 에서 신용카드 정보를 넣어두는 것이 좋습니다. 추후 설치할 addon에서 신용카드 정보가 없으면 진행할 수 없습니다.

Heroku toolbelt 설치

https://toolbelt.heroku.com/ 에서 환경에 맞는 toolbelt를 설치합니다. 저는 지금 linux를 설치하고 있기 때문에, linux 용 toolbelt를 설치한 기준으로 아래 글을 계속 이어가도록 하겠습니다.

설치후, heroku cmd를 사용할 수 있습니다.

Heroku toolbelt 인증 정보 + ssh public key 전송

heroku toolbelt를 설치하면 heroku cmd를 사용해서 인증정보를 입력합니다. heroku service에 가입한 email과 password를 넣어주면 됩니다. 그리고 ssh public key를 heroku에 등록시켜 이제는 heroku email/password가 아닌 ssh key인증을 이용해서 heroku cmd를 사용할 수 있습니다.

$> heroku login Enter your Heroku credentials. Email: Password: Could not find an existing public key. Would you like to generate one? [Yn] Generating new SSH public key. Uploading ssh public key /Users/adam/.ssh/id_rsa.pub

Application의 준비

기본적으로 heroku toolbelt를 이용한 application의 배포는 git를 이용합니다. local 또는 http://github.com 에서 제공되는 git repository에 project가 등록되어 있어야지 됩니다.

java의 pom.xml이나 build.gradle과 같은 기능을 하는 것이 package.json 입니다. 여기에 모든 dependency가 기록되어있어야지 됩니다.

그리고, scripts 항목의 start에 반드시 application의 실행 node command를 넣어줘야지 됩니다. 다음은 scripts 항목의 예시입니다.

"scripts" : { "start" : "node app.js" , "test" : "grunt jasmine" }

개인적으로 이부분에서 실수를 한것이, 제 개발환경이 express가 global로 설치가 되어있습니다. 그래서 express가 package.json에 등록되어있지 않았습니다. 이렇게 되는 경우, dependency 문제로 인하여 application이 정상적으로 동작하지 않습니다. 반드시 package.json 정보만으로 application이 구동될 수 있어야지 됩니다.

git repository와 heroku repository 간의 연결

git repository directory안에서 다음 command를 실행합니다.

$> heroku create --http-git Creating sharp-rain- 871 ... done, stack is cedar- 14 http://sharp-rain- 871 .herokuapp.com/ | https://git.heroku.com/sharp-rain- 871 .git Git

위 command의 결과, git는 remote repository를 하나 더 만들게 됩니다. 이 remote repository에 우리가 appliation을 배포하면 heroku에서 running되는 application을 구성하게 되는 것입니다.

위 console 창의 결과는 sharp-rain-871 이라는 application의 이름을 갖게 됩니다. 이 이름은 unique 한 결과이며, 변경을 원하는 원하는 경우, heroku apps:rename 명령어를 통해 변경할 수 있습니다. 모든 action은 위 git repository directory 안에서 실행되어야지 됩니다.

git repository에서 heroku repository로 deploy

git repository directory안에서 다음 command를 실행합니다.

$> git push heroku master Counting objects: 7 , done. Delta compression using up to 4 threads. Compressing objects: 100 % ( 3 / 3 ), done. Writing objects: 100 % ( 3 / 3 ), 386 bytes | 0 bytes/s, done. Total 3 (delta 2 ), reused 0 (delta 0 )

deploy가 마치면 heroku open command를 통해서 browser를 이용해서 application이 구동되고 있는 것을 확인할 수 있습니다.

heroku는 cloud platform입니다. instance의 갯수를 제어할 수 있습니다. instance를 1개 이상 사용하는 경우, 비용이 발생하기 때문에 주의가 필요합니다.

$> heroku ps:scale web= 1

bower를 이용한 javascript module dependency 처리

bower를 이용하는 경우, javascript를 각각의 repository에서 다운 받아 처리하게 됩니다. 따라서 bower components의 경우, repository에 올라가지 않는 것이 원칙입니다. 따라서, heroku에 배포된 application은 bower components가 하나도 없게 됩니다.

개발환경에서 bower install 을 통해서 bower components들을 얻어주는 것과 같이 heroku에서도 이와 같은 action이 필요하게 됩니다. heroku의 nodejs 환경에는 아무런 환경이 없다고 생각해야지 됩니다. 이를 해결하기 위해서 bower 자체를 dependency에 추가해야지 됩니다.

npm install bower --save

bower를 추가후, package.json 파일의 scripts 항목에 다음을 추가한 후, heroku에 배포를 다시 진행합니다.

"scripts" : { "start" : "node app.js" , "test" : "grunt jasmine" , "postinstall" : "bower install" },

이제 application을 정상적으로 설치하는 과정이 모두 마쳐졌습니다.

mongodb 설치

제가 만든 application은 mongodb를 사용하고 있습니다. mongodb는 heroku에서 addon 형태로 제공하고 있습니다. 500M 까지는 무료로 사용할 수 있으니, 아주 작은 application의 경우에는 언제나 무료로 사용할 수 있습니다. compose mongoDb에 대한 소개는 다음 URL에서 확인 가능합니다. https://devcenter.heroku.com/articles/mongohq

mongodb addon의 설치는 다음과 같습니다.

$> heroku addons:add mongohq

여기서, billing information이 설정되어 있지 않으면 addon의 설치는 진행되지 않습니다. 주의가 필요합니다.

mongodb 연결

compose mongodb를 설치하면, ENV에서 db connection url을 확인할 수 있습니다. config 값의 확인은 다음과 같습니다.

$> heroku config === my-sadari Config Vars MONGOHQ_URL: mongodb://heroku:Xucs9HmJrBKBr6bPkO6CM044_G6oVv5gV0bN0dxcXS-LYHWmKdWXaPnqcYwa7MQn1iVyOmbrP4BRT8QkdJcxlQ@dogen.mongohq.com: 10058 /app31973614

이제 이 값을 이용하는 nodejs code는 다음과 같습니다.

db: process.env.MONGOHQ_URL

mondodb data import/export

개발환경에서의 mongodb의 값을 heroku에 옮겨야지 되는 경우는 자주 발생합니다. 기본적인 key값이라던지, 초기값들을 넣어주는 작업들은 반드시 필요한 작업들입니다. 이러한 작업을 application에서 해주는 것도 좋지만, 개발중인 mongodb의 값을 eport 시킨 후, import 시켜주는 것이 보다 더 편합니다.

이를 위해서는 먼저 원 데이터의 export가 필요합니다.

기본적인 export command는 다음과 같습니다.

mongoexport --collection --out

각 collection 당 json 파일을 만들어야지 되는 것을 까먹으면 안됩니다.

이제 heroku mongodb로 값을 export 시켜야지 됩니다. heroku deshboard로 가면 설치된 addon들을 모두 볼 수 있습니다. (아래의 무료 Plan은 이제 없습니다. 기존에 사용하고 있던 사람들은 계속 사용가능합니다.)

click 하면 Compose MongoDB configuration 화면을 볼 수 있습니다.

여기서 Admin으로 들어가서 새로운 사용자를 하나 만들어줍니다.

이제 만들어진 사용자로, import를 진행할겁니다. 이 관리자 console에서 remote url을 확인 할 수 있습니다.

위 정보를 이용해서 mongodb import는 다음 command를 이용해서 처리가 가능합니다.

mongoimport --host dogen.mongohq.com --port 10058 --username --password --collection --db app31973614 --file

Summary

heroku에 nodejs를 이용한 appliation 배포에 대해서 알아봤습니다. 제가 속한 팀에서의 점심후의 사다리타기 결과를 모아둔 heroku app을 공개해뒀습니다. ㅋㅋ (http://my-sadari.herokuapp.com) heroku는 300M까지는 무료입니다. 이 점에서 nodejs의 가벼운 code의 강점이 보이는 것 같습니다. 아무리 가벼운 웹이라도 은근히 용량이 되는 경우가 많으니까요.

그럼 모두 Happy Coding!

from http://netframework.tistory.com/444 by ccl(S)

댓글

이 블로그의 인기 게시물

카카오 오픈빌더와 외부 API 연동(feat.Nodejs)

카카오 오픈빌더와 외부 API 연동(feat.Nodejs) 이전에 플러스 친구와 외부 API 연동에 관한 글을 작성한 적 있습니다. 하지만 지난 2년동안 플러스 친구에 많은 변화가 생겼는데요. 카카오 플러스 친구의 명칭이 카카오 채널로 바뀌고, 챗봇 세팅 방식이 기존 [카카오 플러스 친구 - 외부 API 연동] 구조에서 오픈빌더가 추가되어 [카카오 채널(구 플러스 친구) - 카카오 i 오픈빌더 - 외부 API 연동] 구조로 바뀌었습니다. 이번 글에서는 오픈빌더의 챗봇 시나리오 관리 기능을 간단히 소개하고 외부 API를 연동하는 예제를 다뤄보겠습니다. (연동파트는 5번 항목부터 보시면 됩니다.) 1. 블록 블록은 오픈빌더에서 질의/응답을 관리하는 최소 단위로, 사용자의 발화와 챗봇의 대답을 입력할 수 있습니다. 예를들어 인사라는 블록을 만들고 인사에 해당하는 사용자 발화 패턴들을 입력해두면, 실제 채널 톡방에서 그에 해당하는 발화가 들어왔을때 입력해둔 응답이 나오는 형식입니다. 예전에는 패턴과 발화 키워드가 1:1 매칭, 즉 입력해둔 패턴과 사용자 발화의 string이 정확히 일치할때만 블록이 실행됐었는데, 발화 패턴을 20개 이상 등록하면 머신러닝 기능을 이용할 수 있도록 기능이 생겼습니다. 아마 유사도 분석 개념이 기본으로 들어가있을 것이기 때문에 블록의 주제와 벗어나는 너무 뜬금없는 발화패턴들을 많이 넣지 않도록 하는걸 권장하겠습니다. 2. 시나리오 시나리오는 '블록'들을 묶어서 관리할 수 있는 단위로, 일종의 폴더 구조라고 생각하면 쉽습니다. 오픈빌더에서 좌측 상단에 파란 버튼을 클릭하여 시나리오를 생성할 수 있습니다. 하나의 시나리오에서 모든 블록을 관리하면 챗봇 도메인이 커질수록 관리가 어려워지니 아래 같은식으로 시나리오를 사용하여 블록을 구조화하면 운영 측면에서 수월해집니다. 3. 컨텍스트 컨텍스트는 맥락이라는 뜻 입니다. 오픈빌더에 존재하는 컨텍스트는 자연어 분석을 통해서 맥...

AWS instance로 Nodejs 구현하기

AWS instance로 Nodejs 구현하기 서버와 데이터베이스 관리 차원에서 효율적으로 관리하기 위해선 로컬보다는 서버를 호스팅해서 하는 것이 좋다. 우리는 Nodejs를 구동하기 위해 AWS에서 인스턴스를 할당받을 계획이다. 인스턴스의 pem키를 발급받아 nodejs와 npm까지는 설치를 완료한 상태이다. $ sudo npm install -g express 다음의 명령어를 입력하면 글로벌 옵션으로 어느 path에서든 express를 사용할 수 있게 설치한다. 다음과 같이 실행이 된다면 성공이다. 이후 Express generator를 설치한다. $ sudo npm install -g express-generator@4 버전은 4.x이며 이 역시 글로벌 옵션으로 설치해 준다. 이제 Node monitoring을 위해 nodemon을 설치해 준다. $ sudo npm install -g nodemon 모든 설치가 끝났다. 이제 nodejs를 실행시킬 프로젝트용 directory를 만든다. 이렇게 만들어 주고 express를 실행시키면 된다. $ express -e 다음과 같은 결과가 나오면 된다. 이제 node package를 설치하는 명령어를 입력하자. $ sudo npm install 이제 vi를 통해 포트번호를 정의해보자. app.set의 마지막에 한줄을 추가하면 된다. app.set('port', process.env.PORT || 9000); 이로써 우리는 9000번 포트를 사용하게 되었다. 또한 마지막줄에 서버를 생성하기 위한 코드를 작성하자. module.exports = app; var server = app.listen(app.get('port'), function() { console.log('Express server listening on port ' + server.address().port); }); 이...

20.03.24 ShareBook TIL

20.03.24 ShareBook TIL Project/TIL 20.03.24 ShareBook TIL 중간 배포를 위해 EC2, RDS를 다시 설정하였다. EC2에 git에서 clone을 하고 서버를 작동시켜보니 ts로 돌려서 그런지 작동하지 않고 대기 상태로 있다가 timeout같은 시간 초과 에러가 났다. 그리고 갑자기 EC2 자체가 느려져서 nodejs를 삭제하고 다시 nvm으로 높은 버전의 node를 설치하였다. 그리고 나서 혹시 js로 돌리면 될까 해서 tsc로 js로 변환한뒤 돌려보니 RDS와 연결이 되지 않는 에러가 생겼다. workbench로 RDS를 연결했을 때는 정상적으로 작동해서 EC2에서 잘 못 설정한게 있다고 생각했다. 그래서 local에서 한번 config.json을 수정하고 연결하여도 똑같은 에러가 발생했다. 그럼 보안 설정에서 문제인가 싶어서 EC2, RDS 보안 그룹에서 설정을 막 만져보다 RDS에서 Custom TCP에 처음 RDS에서 설정한 포트를 넣어주었더니 연결되었다. config.json내용을 EC2에도 똑같이 적용시켜보려고 json파일을 vim으로 작성해서 넣어 주었지만 여전히 같은 에러를 반복하였다. 그럼 json 파일을 못 읽어내는게 아닌가 싶어서 그냥 module에 index.js에서 sequelize를 생성하는 부분에 직접 넣어 주었더니 마침내 연결이 되었다. 해결하고 난 뒤 생각의 흐름을 적어보니 매우 짧지만 정작 오늘 아침 10시 반부터 시작해서 저녁 10시 반까지 12시간을 고민하고나서야 해결되었다. from http://three-five.tistory.com/46 by ccl(A) rewrite - 2020-03-25 00:54:05