ミニマムでNode.jsのサーバーをHerokuで動かす。
Herokuの公式 ( https://devcenter.heroku.com/articles/getting-started-with-nodejs ) は、Expressを使っているのだが、https://github.com/heroku/node-js-getting-started をCloneしているのでなんか微妙。
Generatorで作らない場合は、以下を参照すると良かった。
- Express Generatorを使わない場合
- http://qiita.com/hoshi-takanori/items/2128a6cf1dbb533379a2
- 特にGithubのコミットを一個ずつ見ると分かりやすい
- Expressすら使わない場合
- http://howtonode.org/deploy-blog-to-heroku
ソースコード
2コミットで出来ました。ごめんなさい。
準備
Node.jsのインストール
brew install node
Expressのインストール
ExpressはNode.jsでメジャーっぽいアプリケーションフレームワーク。
Express4以降npm install express
ではgeneratorは入らない。
express-generator
をnpm
を使ってグローバルに入れる。
npm install express-generator -g
ソースコードの準備
ExpressテンプレートをGenerate
express express-sample
一応git init
しておく
cd express-sample
git init
git add .
git commit -m "express express-sample"
.gitignoreの設置
Node用の.gitignore
を
https://github.com/github/gitignore/blob/master/Node.gitignore
から頂いて用意。
.DS_Store
とかを入れない記述もついでに。
git add .gitignore
git commit -m "Add .gitignore"
npm install
{
"name": "express-sample",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.12.0",
"cookie-parser": "~1.3.4",
"debug": "~2.1.1",
"express": "~4.12.2",
"jade": "~1.9.2",
"morgan": "~1.5.1",
"serve-favicon": "~2.2.0"
}
}
のdependencies
部分に書いているモジュールのインストール
npm install
node_modules
ディレクトリができ、それいかに配置される。
node_modules
は.gitignore
に設定されているのでgitではトラックされないはず
ローカルでサーバーの起動
bin/www
もしくは
npm start
これはpackage.json
のscripts.start
の部分にかいてあるから
を叩く
Herokuでサーバーの起動
heroku create
git push heroku master
heroku open
でサーバーが立つ。
何をしているか
何故、これだけで起動するか、ぱっとわからなかったので、Herokuにpushした時のログを見て解釈してみた。
Herokuアプリは大体以下の様なことができていれば動く。
- 何のフレームワークか認識してもらい、それに対応したビルドパックで起動してもらい、必要なDependencyとかをインストールしてもらう
- Port番号を環境変数からとるようにする
- Procfileに起動方法を書く
このそれぞれについて、しっかり対応されているので動く。
1.は、まぁHerokuが対応しているというので出来るでしょという感じ。package.json
の存在とか見ているのだろうか?
なんにせよremote: -----> Node.js app detected
となっているのでOK。
2.は、expressがgenerateしたbin/www
内でvar port = normalizePort(process.env.PORT || '3000');
となっているので大丈夫。
3.は、expressがpackage.json
にscript.start
をしっかり定義しているのと、Heroku側が、Procfileがなかった時にNo Procfile; Adding 'web: npm start' to new Procfile
というように、npm start
を勝手に足してくれる設定になっていることで実現されている。
$ git push heroku master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (19/19), 3.49 KiB | 0 bytes/s, done.
Total 19 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Reading application state
remote: package.json...
remote: build directory...
remote: cache directory...
remote: environment variables...
remote:
remote: Node engine: unspecified
remote: Npm engine: unspecified
remote: Start mechanism: npm start
remote: node_modules source: package.json
remote: node_modules cached: false
remote:
remote: NPM_CONFIG_PRODUCTION=true
remote: NODE_MODULES_CACHE=true
remote:
remote: -----> Installing binaries
remote: Resolving node version (latest stable) via semver.io...
remote: Downloading and installing node 0.12.3...
remote: Using default npm version: 2.9.1
remote:
remote: -----> Building dependencies
remote: Installing node modules
remote: debug@2.1.3 node_modules/debug
remote: └── ms@0.7.0
remote:
remote: cookie-parser@1.3.4 node_modules/cookie-parser
remote: ├── cookie-signature@1.0.6
remote: └── cookie@0.1.2
remote:
remote: morgan@1.5.3 node_modules/morgan
remote: ├── basic-auth@1.0.1
remote: ├── depd@1.0.1
remote: ├── debug@2.2.0 (ms@0.7.1)
remote: └── on-finished@2.2.1 (ee-first@1.1.0)
remote:
remote: serve-favicon@2.2.1 node_modules/serve-favicon
remote: ├── fresh@0.2.4
remote: ├── ms@0.7.1
remote: ├── parseurl@1.3.0
remote: └── etag@1.6.0 (crc@3.2.1)
remote:
remote: express@4.12.3 node_modules/express
remote: ├── cookie-signature@1.0.6
remote: ├── cookie@0.1.2
remote: ├── fresh@0.2.4
remote: ├── merge-descriptors@1.0.0
remote: ├── content-type@1.0.1
remote: ├── utils-merge@1.0.0
remote: ├── parseurl@1.3.0
remote: ├── methods@1.1.1
remote: ├── escape-html@1.0.1
remote: ├── range-parser@1.0.2
remote: ├── finalhandler@0.3.4
remote: ├── vary@1.0.0
remote: ├── content-disposition@0.5.0
remote: ├── path-to-regexp@0.1.3
remote: ├── depd@1.0.1
remote: ├── on-finished@2.2.1 (ee-first@1.1.0)
remote: ├── qs@2.4.1
remote: ├── etag@1.5.1 (crc@3.2.1)
remote: ├── proxy-addr@1.0.8 (forwarded@0.1.0, ipaddr.js@1.0.1)
remote: ├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
remote: ├── serve-static@1.9.3 (send@0.12.3)
remote: ├── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
remote: └── accepts@1.2.7 (negotiator@0.5.3, mime-types@2.0.11)
remote:
remote: body-parser@1.12.4 node_modules/body-parser
remote: ├── content-type@1.0.1
remote: ├── bytes@1.0.0
remote: ├── depd@1.0.1
remote: ├── on-finished@2.2.1 (ee-first@1.1.0)
remote: ├── qs@2.4.2
remote: ├── debug@2.2.0 (ms@0.7.1)
remote: ├── raw-body@2.0.1 (bytes@2.0.1)
remote: ├── iconv-lite@0.4.8
remote: └── type-is@1.6.2 (media-typer@0.3.0, mime-types@2.0.11)
remote:
remote: jade@1.9.2 node_modules/jade
remote: ├── character-parser@1.2.1
remote: ├── void-elements@2.0.1
remote: ├── commander@2.6.0
remote: ├── mkdirp@0.5.1 (minimist@0.0.8)
remote: ├── with@4.0.3 (acorn-globals@1.0.4, acorn@1.1.0)
remote: ├── constantinople@3.0.1 (acorn-globals@1.0.4)
remote: └── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)
remote:
remote: -----> Checking startup method
remote: No Procfile; Adding 'web: npm start' to new Procfile
remote:
remote: -----> Finalizing build
remote: Creating runtime environment
remote: Exporting binary paths
remote: Cleaning npm artifacts
remote: Cleaning previous cache
remote: Caching results for future builds
remote:
remote: -----> Build succeeded!
remote:
remote: express-sample@0.0.0 /tmp/build_3fd93387a2b876ab90201bf2c61aae41
remote: ├── body-parser@1.12.4
remote: ├── cookie-parser@1.3.4
remote: ├── debug@2.1.3
remote: ├── express@4.12.3
remote: ├── jade@1.9.2
remote: ├── morgan@1.5.3
remote: └── serve-favicon@2.2.1
remote:
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing... done, 10.4MB
remote: -----> Launching... done, v3
remote: https://salty-river-9329.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/salty-river-9329.git
* [new branch] master -> master
とても簡単に起動できた。
最近Railsやっていてもフロント周りでNode.jsの知識がちょっと必要になったり、
Native appを作れるElectronとかもNode.jsの知識必要だったりするから、
これを元にNode周りの技術を色々いじってみようと思う。