Node.jsアプリの継続動作には今までforever使ってたんですが、pm2は色々親切で高機能なので乗り換えることにしました。pm2を使うようにデプロイしてみましょう。
Ansible
デプロイするためには普通sshで入ってgit pullしてとかやらなきゃいけないですが、1個1個手でやるのは忘れやすいし間違いやすいのでAnsibleを使います。
Ansibleはあれやってこれやってを列挙しておけるもので、それを実行すると順番に全部やってくれます。
詳しくはhttp://yteraoka.github.io/ansible-tutorial/とか見てください。
では、node.jsもgitも何も入っていないubuntuに手元のnode.jsを入れるとします。
ただし、sshでは入ることが出来るように公開鍵はセットされてて、sudoはパスワード無しで出来るユーザーだとします。ここまではよろしくね。
apt-get
まず。
- Node.js
- npm
- pm2
- Git
を入れます。
--- # Install Node.js(include npm) pm2 - name: Prepare Install Node.js apt: name=python-software-properties - name: Prepare Install latest Node.js by adding repo apt_repository: repo='ppa:chris-lea/node.js' - name: Update apt-get packages using apt-get update apt: update_cache=yes - name: Install Node.js apt: name=nodejs state=present - name: Install pm2 npm: name=pm2 global=yes state=latest # Install Git - name: Install Git apt: name=git state=present
ここまででapt-get系は終了です。
apt-getするので、sudo=yesがplaybookに必要です。
ちなみにnode.jsとnpmは一緒に入ってきますのでご心配なく。そしてそれが入るとAnsibleのnpmモジュールでnpmの操作ができるようになります。
こうやって何かが入っていないと実行できない場合は -checkをつかったテスト実行だと失敗しますが、ちゃんとした実行だとnpmも入るわけですからうまく動きます。
また、今回は最新のnode.jsを入れたかったのでchris-leaのリポジトリを利用しています。
git pull
node.jsアプリをgit 経由でデプロイしましょう。
git pullする時に気にするのは鍵です。公開リポジトリならいいですが、そうでない場合対象となるサーバーがリポジトリにアクセスできるかが問題になります。方法として
- deploy用の秘密鍵をそもそも自分で秘密鍵を入れておく
- deploy用の秘密鍵をAnsibleで入れて使うようにする
- 手元の秘密鍵をforwardする
などの手があります。2とかがキレイですが、どうせ手元からしかやらないのであれば3はオススメです。そのための設定がいるが必要でansible.cfgをplaybookと同じディレクトリに置きます。内容は
[ssh_connection] ssh_args = -o ForwardAgent=yes
とします。
また、ansible-playbookする時に
--private-key=~/.ssh/id_rsa
といった感じでリポジトリにアクセスできる秘密鍵を指定するようにします。これで手元の秘密鍵がgit pull の時に使われるので問題なくpullできます。
実際のtaskは
--- # Deployment - name: Create Target Directory. file: state=directory path={{app_dir}}/{{app_name}} mode=0755 - name: Change Owner file: owner={{deploy_user}} state=directory path={{app_dir}}/{{app_name}} recurse=yes - name: Pull code from Repository sudo: no git: repo={{repo_url}} dest={{app_dir}}/{{app_name}} version=master accept_hostkey=yes - name: npm install npm: path={{app_dir}}/{{app_name}} - name: List of Node.js apps running. sudo: no shell: pm2 list register: node_app_list changed_when: false tags: restart - name: Stop old process if exist sudo: no command: pm2 stop {{app_process_name}} when: node_app_list.stdout.find('{{app_process_name}}') != -1 tags: restart - name: Start process with pm2 sudo: no command: pm2 start {{app_dir}}/{{app_name}}/bin/www --name {{app_process_name}} tags: restart
こんな感じです。
同じくsudo=yesが必要です。
ここまでやるとhttp://入れた場所:3000/ とかで動きます。
ちなみにpm2で手動的にプロセスを再起動していますが、pm2にはファイルの変更監視をして変更されてたら再起動するようなwatch機能があるのでそれを使って更新することも可能です。
後はnginxの設定などで特定のサブドメインだったらこのnodeのアプリとかやるといいですね。