さて、Herokuを使って簡単なWebアプリを公開する手順をメモする。
言語としてnode.jsを使うので、現在の公式バージョン node.js 0.6を使える環境を探した。Windowsはそもそもnode.jsとherokuの開発に向いてなさそうなので考慮外。Linuxで探すとDebian 6は少し古いようだ(nodejsをパッケージとして入っていない。apt-getで取得できない)。Ubuntu 12.04ならOK。
Ubuntu12.04を(仮想OSに)インストールして、
apt-get install git nodejs npm
と実行する。herokuにはgitも必要らしいし、node.jsをherokuで使う場合npmも必要らしいからだ。
開発環境のために
apt-get install zsh lv emacs23-nox vsftpd
も実行。
$HOME/.ssh というディレクトリにSSH鍵ファイルを用意しておく。WindowsからWinSCP使ってFTPで転送した。
$HOME/.ssh/id_dsa $HOME/.ssh/id_dsa.pub
Herokuにアクセスするツールを取得。
https://toolbelt.heroku.com/linux
に書いてあるとおり実行。
wget https://toolbelt.heroku.com/install.sh sh ./install.sh
そのあとは
https://devcenter.heroku.com/articles/nodejs
に書いてあるとおり実行。
foo@ubuntu1204sv ~ % heroku login Enter your Heroku credentials. Email: itouhiro@example.com Password (typing will be hidden): Found existing public key: /home/foo/.ssh/id_dsa.pub Uploading SSH public key /home/foo/.ssh/id_dsa.pub Authentication successful. foo@ubuntu1204sv ~ % foo@ubuntu1204sv ~ % mkdir webaborn foo@ubuntu1204sv ~ % cd webaborn foo@ubuntu1204sv ~/webaborn % heroku create --stack cedar Creating pure-stream-5725... done, stack is cedar http://pure-stream-5725.herokuapp.com/ | git@heroku.com:pure-stream-5725.git
これで、名前がwebabornという、中身はまだカラのアプリができたようです。 (←名前は「pure-stream-5725」だぞ。この文書の後のほうで消します)
さてnode.jsでアプリを作るぞ。
https://devcenter.heroku.com/articles/nodejs
によると、npmも必要なのでそれはapt-getで入れた。
そのページに書いてあるweb.jsを実行してみると、expressというフレームワークがインストールされてないというエラー。
foo@ubuntu1204sv ~/webaborn % node web.js node.js:201 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Cannot find module 'express'
expressフレームワークの入れ方だが、
この https://devcenter.heroku.com/articles/nodejs ページとほぼ同じことをやっている
http://www.eiplab.com/2011/06/heroku-node-js-express-helloworld/
によると
$ npm install express
を実行してexpressのバージョンを覚えろ、とのこと。
foo@ubuntu1204sv ~/webaborn % npm install express npm http GET https://registry.npmjs.org/express ... npm http 200 https://registry.npmjs.org/formidable/-/formidable-1.0.9.tgz express@2.5.9 ./node_modules/express ├── qs@0.4.2 ├── mime@1.2.4 ├── mkdirp@0.3.0 └── connect@1.8.7
2.5.9か。
ファイルpackage.jsonを作成する。
{ "name": "webaborn", "version": "0.0.1", "dependencies": { "express": "2.5.9" } }
$ npm install
を実行すると package.jsonを読み込んで何か設定してくれたらしい。
ちなみにpackage.jsonで
"express": "2.5.9",
と最後にコンマを書いたらnpm installがエラーになるので注意。
Procfileというファイルを作り、中にこう書く。
web: node web.js
そのファイルがherokuがファイルを実行するときの指令書のようだ。
そのファイルを読んで実行するコマンドが以下。
$ foreman start
ちゃんと実行できてるな。
さてそれでは開発したファイルをgitに登録する。
まず必要ないファイルは登録しないように設定する。
foo@ubuntu1204sv ~/webaborn % echo "node_modules" > .gitignore foo@ubuntu1204sv ~/webaborn % git config --global user.name "itouhiro" foo@ubuntu1204sv ~/webaborn % git config --global user.email "itou.hiroki@example.com" foo@ubuntu1204sv ~/webaborn % git config --global color.ui "auto" foo@ubuntu1204sv ~/webaborn % git config --global core.pager "lv -c"
それでは登録。
foo@ubuntu1204sv ~/webaborn % git init Initialized empty Git repository in /home/foo/webaborn/.git/ foo@ubuntu1204sv ~/webaborn % git add . foo@ubuntu1204sv ~/webaborn % git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitignore # new file: Procfile # new file: package.json # new file: web.js # foo@ubuntu1204sv ~/webaborn % git commit -m "hello world" [master (root-commit) c068179] hello world 4 files changed, 20 insertions(+) create mode 100644 .gitignore create mode 100644 Procfile create mode 100644 package.json create mode 100644 web.js foo@ubuntu1204sv ~/webaborn %
さてそれではdeploy(Webアプリとして設置)。
foo@ubuntu1204sv ~/webaborn % heroku create --stack cedar Creating stark-day-7906... done, stack is cedar http://stark-day-7906.herokuapp.com/ | git@heroku.com:stark-day-7906.git Git remote heroku added foo@ubuntu1204sv ~/webaborn % git push heroku master The authenticity of host 'heroku.com (50.19.85.132)' can't be established. RSA key fingerprint is 8b:48:5e:67:0e:c9:16:47:32:f2:87:0c:1f:c8:60:ad. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'heroku.com,50.19.85.132' (RSA) to the list of known hosts. Counting objects: 6, done. Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 615 bytes, done. Total 6 (delta 0), reused 0 (delta 0) -----> Heroku receiving push -----> Node.js app detected -----> Resolving engine versions WARNING: No version of Node.js specified in package.json, see: https://devcenter.heroku.com/articles/nodejs-versions Using Node.js version: 0.4.7 Using npm version: 1.0.106 -----> Fetching Node.js binaries -----> Vendoring node into slug -----> Installing dependencies with npm express@2.5.9 ./node_modules/express ├── mkdirp@0.3.0 ├── qs@0.4.2 ├── mime@1.2.4 └── connect@1.8.7 express@2.5.9 /tmp/build_3csnlz01f4x7y/node_modules/express connect@1.8.7 /tmp/build_3csnlz01f4x7y/node_modules/express/node_modules/connect qs@0.4.2 /tmp/build_3csnlz01f4x7y/node_modules/express/node_modules/qs mime@1.2.4 /tmp/build_3csnlz01f4x7y/node_modules/express/node_modules/mime formidable@1.0.9 /tmp/build_3csnlz01f4x7y/node_modules/express/node_modules/connect/node_modules/formidable mkdirp@0.3.0 /tmp/build_3csnlz01f4x7y/node_modules/express/node_modules/mkdirp Dependencies installed -----> Discovering process types Procfile declares types -> web -----> Compiled slug size is 3.3MB -----> Launching... done, v3 http://stark-day-7906.herokuapp.com deployed to Heroku To git@heroku.com:stark-day-7906.git * [new branch] master -> master foo@ubuntu1204sv ~/webaborn %
あれれ、node.jsのバージョン0.4で動いてるじゃないか。package.jsonの書き方に不備があったらしい。
まあ動作はするだろう。
プロセス数を指定?する必要があるようだ。
foo@ubuntu1204sv ~/webaborn % heroku ps:scale web=1 Scaling web processes... done, now running 1 foo@ubuntu1204sv ~/webaborn % heroku ps Process State Command ------- --------- ----------- web.1 up for 2m node web.js foo@ubuntu1204sv ~/webaborn % heroku ps:scale web=0
とするとプロセスなくなるので停止ということかな。
foo@ubuntu1204sv ~/webaborn % heroku logs 2012-05-16T09:07:26+00:00 heroku[slugc]: Slug compilation started 2012-05-16T09:07:37+00:00 heroku[api]: Config add PATH by itou.hiroki@example.com 2012-05-16T09:07:37+00:00 heroku[api]: Release v2 created by itou.hiroki@example.com 2012-05-16T09:07:37+00:00 heroku[api]: Deploy c068179 by itou.hiroki@example.com 2012-05-16T09:07:37+00:00 heroku[api]: Release v3 created by itou.hiroki@example.com 2012-05-16T09:07:38+00:00 heroku[web.1]: State changed from created to starting 2012-05-16T09:07:38+00:00 heroku[slugc]: Slug compilation finished 2012-05-16T09:07:39+00:00 heroku[web.1]: Starting process with command `node web.js` 2012-05-16T09:07:40+00:00 app[web.1]: listening on 18011 2012-05-16T09:07:40+00:00 heroku[web.1]: State changed from starting to up 2012-05-16T09:10:20+00:00 heroku[api]: Scale to web=1 by itou.hiroki@example.com foo@ubuntu1204sv ~/webaborn %
Expressフレームワーク使ってる場合、以下を実行らしい‥‥。
foo@ubuntu1204sv ~/webaborn % heroku config:add NODE_ENV=production Adding config vars and restarting app... done, v4 NODE_ENV => production
↑これはやはり完成版に使うべきだった様子。未完成なら使わなくてよいと思う。
foo@ubuntu1204sv ~/webaborn % heroku open Opening http://stark-day-7906.herokuapp.com/ Failure in opening http://stark-day-7906.herokuapp.com/ with options {}: Unable to find a browser command. If this is unexpected, Please rerun with environment variable LAUNCHY_DEBUG=true or the '-d' commandline option and file a bug at https://github.com/copiousfreetime/launchy/issues/new foo@ubuntu1204sv ~/webaborn %
あれー。確かに http://stark-day-7906.herokuapp.com/ は動いてる。
http://webaborn.herokuapp.com/ は動いてないじゃないか。
http://kray.jp/blog/twitter_service_in_1hours/
Herokuはコマンドラインからheroku create コマンドで、プロジェクトを登録できます。
% heroku create twitter-helloworld
twitter-helloworldは適宜変更してください。すでに利用されているプロジェクト名は使えません。
そういうことなのか。
確かにログにも
foo@ubuntu1204sv ~/webaborn % heroku create --stack cedar Creating stark-day-7906... done, stack is cedar http://stark-day-7906.herokuapp.com/ | git@heroku.com:stark-day-7906.git
と残ってるな。
これでいろいろ試してみよう。
とりあえず Node.jsとnpmのバージョンを指定した。
package.json:
{ "name": "webaborn", "version": "0.0.1", "dependencies": { "node": "0.6.12", "npm": "1.1.4", "express": "2.5.9" } }
foo@ubuntu1204sv ~/webaborn % git add . foo@ubuntu1204sv ~/webaborn % git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: package.json # foo@ubuntu1204sv ~/webaborn % git commit -m "specify version of node.js and npm" [master 00b5df8] specify version of node.js and npm 1 file changed, 2 insertions(+) foo@ubuntu1204sv ~/webaborn % git log
↑こうすると、npm install が通らなくなる。まずいかも
←文法まちがってただけ。
{ "name": "webaborn", "version": "0.0.1", "engines": { "node": "0.6.12", "npm": "1.1.4" }, "dependencies": { "express": "2.5.9" } }
だとnpm install通る。
foo@ubuntu1204sv ~/webaborn % git push heroku master
これで動作した。
作成したプロジェクトを消す方法
foo@ubuntu1204sv ~/webaborn % heroku apps --help apps:create [NAME] # apps:create [NAME] apps:destroy # apps:destroy apps:info # apps:info apps:open # apps:open apps:rename NEWNAME # apps:rename NEWNAME foo@ubuntu1204sv ~/webaborn % heroku apps:destroy --app pure-stream-5725 ! WARNING: Potentially Destructive Action ! This command will destroy pure-stream-5725 (including all add-ons). ! To proceed, type "pure-stream-5725" or re-run this command with --confirm pure-stream-5725 > pure-stream-5725 Destroying pure-stream-5725 (including all add-ons)... done
さて新しくWebApp作るよ。
foo@ub1204 ~ % heroku login Enter your Heroku credentials. Email: itou.hiroki@example.com Password (typing will be hidden): Authentication successful. foo@ub1204 ~ % heroku apps:create webaborn -s cedar ! Notice: on Wed, 20 June, our default stack will change to Cedar. http://bit.ly/Lh0rM5 Creating webaborn... done, stack is cedar http://webaborn.herokuapp.com/ | git@heroku.com:webaborn.git foo@ub1204 ~ %
-s cedar
とはどういう意味か?
--stack
でも同じだけど、stackというのはOSと言語バージョンのこと。
https://devcenter.heroku.com/articles/stack
'cedar'というのはUbuntu10.04にnode.jsとか載ってるstackの名前。node.js使えるのはこれしかないし、今では
デフォルトもこれ。
スクリプトをコピーして、確認。
foo@ub1204 ~/webaborn % cp -p ~/share/wbab/* . foo@ub1204 ~/webaborn % lv webaborn.js foo@ub1204 ~/webaborn % lv webaborn.html foo@ub1204 ~/webaborn % lv template-webaborn-jssearch.js foo@ub1204 ~/webaborn % lv template-webaborn-xpathsearch.js foo@ub1204 ~/webaborn % emacs webaborn.js package.json { "name": "webaborn", "version": "13.0.0", "dependencies": { }, "engines": { "node": "0.6.x" } } Procfile web: node webaborn.js
foo@ub1204 ~/webaborn % npm install
ふむ。問題なし。
foo@ub1204 ~/webaborn % echo node_modules > .gitignore
動作確認。
foo@ub1204 ~/webaborn % foreman start 18:55:00 web.1 | started with pid 1512 18:55:00 web.1 | Listening on 5000 ^CSIGINT received 18:55:57 system | sending SIGTERM to all processes 18:55:57 system | sending SIGTERM to pid 1512 18:55:57 web.1 | process terminated
動くよ。
foo@ub1204 ~/webaborn % git config -l foo@ub1204 ~/webaborn % git config --global user.name "itouhiro" foo@ub1204 ~/webaborn % git config --global user.email "itou.hiroki@example.com" foo@ub1204 ~/webaborn % git config --global color.ui "auto" foo@ub1204 ~/webaborn % git config --global core.pager "lv -c" foo@ub1204 ~/webaborn % git config -l user.name=itouhiro user.email=itou.hiroki@example.com color.ui=auto core.pager=lv -c foo@ub1204 ~/webaborn % git init Initialized empty Git repository in /home/foo/webaborn/.git/ foo@ub1204 ~/webaborn % git add . foo@ub1204 ~/webaborn % git status # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: .gitignore # new file: Procfile # new file: package.json # new file: template-webaborn-jssearch.js # new file: template-webaborn-xpathsearch.js # new file: webaborn.html # new file: webaborn.js # foo@ub1204 ~/webaborn % git commit -m "version 13 RC" [master (root-commit) 3201e2d] version 13 RC 7 files changed, 627 insertions(+) create mode 100644 .gitignore create mode 100644 Procfile create mode 100644 package.json create mode 100644 template-webaborn-jssearch.js create mode 100644 template-webaborn-xpathsearch.js create mode 100644 webaborn.html create mode 100644 webaborn.js foo@ub1204 ~/webaborn % git push heroku master fatal: 'heroku' does not appear to be a git repository fatal: The remote end hung up unexpectedly
なんですかこのエラーは。どうもgit repository構築前にheroku apps:createしてしまったのがまずかったようだ。
http://stackoverflow.com/questions/2294024/cloned-project-from-github-heroku-does-not-work
foo@ub1204 ~/webaborn % git remote add heroku git@heroku.com:webaborn.git
とくに何もいわないけどこれでつながったようだ。
foo@ub1204 ~/webaborn % git push heroku master The authenticity of host 'heroku.com (50.19.85.132)' can't be established. RSA key fingerprint is 8b:48:5e:67:0e:c9:16:47:32:f2:87:0c:1f:c8:60:ad. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'heroku.com,50.19.85.132' (RSA) to the list of known hosts. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: UNPROTECTED PRIVATE KEY FILE! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Permissions 0666 for '/home/foo/.ssh/id_dsa' are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. bad permissions: ignore key: /home/foo/.ssh/id_dsa Permission denied (publickey). fatal: The remote end hung up unexpectedly
ファイルのpermissionを修正。
foo@ub1204 ~/webaborn % ls -l ~/.ssh/ total 16 -rw-rw-rw- 1 foo foo 668 Feb 5 2011 id_dsa -rw-rw-rw- 1 foo foo 1313 Feb 5 2011 id_dsa.OpenSSH.txt -rw-rw-rw- 1 foo foo 600 Feb 5 2011 id_dsa.pub -rw-r--r-- 1 foo foo 884 Jun 16 19:15 known_hosts foo@ub1204 ~/webaborn % chmod 600 ~/.ssh/id_dsa
もう一度deploy
foo@ub1204 ~/webaborn % git push heroku master Warning: Permanently added the RSA host key for IP address '50.19.85.156' to the list of known hosts. Counting objects: 9, done. Compressing objects: 100% (7/7), done. Writing objects: 100% (9/9), 13.55 KiB, done. Total 9 (delta 0), reused 0 (delta 0) -----> Heroku receiving push -----> Node.js app detected -----> Resolving engine versions Using Node.js version: 0.6.18 Using npm version: 1.0.106 -----> Fetching Node.js binaries -----> Vendoring node into slug -----> Installing dependencies with npm Dependencies installed -----> Discovering process types Procfile declares types -> web -----> Compiled slug size is 3.2MB -----> Launching... done, v3 http://webaborn.herokuapp.com deployed to Heroku To git@heroku.com:webaborn.git * [new branch] master -> master foo@ub1204 ~/webaborn %
起動させるぞ。
foo@ub1204 ~/webaborn % heroku ps:scale web=1 Scaling web processes... done, now running 1
確認。
foo@ub1204 ~/webaborn % heroku ps === web: `node webaborn.js` web.1: up for 1m
http://webaborn.herokuapp.com をブラウザで確認。