HerokuからさくらVPSのubuntu12.04にRailsアプリケーションを移行したときのメモ


基本的にRailscastsの#335 Deploying to a VPSの通りに作業しました。
http://railscasts.com/episodes/335-deploying-to-a-vps?view=asciicast
Railscasts proに入らないと見られないです。
そしてこの記事では、上記のページの補足、Railscastsのままではうまくいかなかった点を書きます。なので、Railscasts#335で説明されていることは書きません。Railscasts proに入って、まずは http://railscasts.com/episodes/335-deploying-to-a-vps?view=asciicast を見てください。

# 本番環境の設定

さくらVPSの解説はこちらで。
http://dotinstall.com/lessons/basic_sakura_vps
\#1〜#10まで見たら大丈夫。#11以降は見なくてよいです。ドットインストールで紹介されているApacheではなく、Webサーバにnginxを使うので問題ありません。

## Ubuntuインストール

さくらのVPS公式ガイドを見ながらまずはUbuntu 12.04をカスタムインストール。
http://support.sakura.ad.jp/manual/vps/mainte/custom_ubuntu1204.html

キーボードレイアウトをJapaneseにしたところ、問題が発生。

なぜか日本語入力で、Alt + Ctrlを押しても直接入力に戻せない。
しかたがないので、Configure the keyboardでEnglish(US)を選択して直した。

インストールの際に、rootではないユーザーのkatryoを作成する。
以後、基本的にこの新ユーザーとして作業します。
インストールが完了したら、なにはともあれセキュリティ。


## sshdの設定
http://blog.livedoor.jp/oceanweb/archives/18082178.html
この記事を参考に、まずはsshdを設定。接続ポートを変更します。
/etc/ssh/sshd_configを探して、

```/etc/ssh/sshd_config 
#Port 22
```

となっているところを

```/etc/ssh/sshd_config 
Port 10022 #1024から65535までの任意の整数
```

に変えます。そしてRootログインを制限するため

```/etc/ssh/sshd_config 
PermitRootLogin no
```

にします。初期設定でこうなってるかもです。

## RSA公開鍵を本番環境サーバに送信

さくらVPSは、ブラウザで動かせる環境としてリモートコンソールを提供しています。リモートコンソールの上部には、長い文字列を入力できるコピペボタンがあります。

本番環境サーバにはクリップボードを受け渡せないので、コピペボタンは非常にありがたい。

はずなのですが、コピペ以前にまともに反応しません。なので、開発環境側からscpでrsa.pubを送信しました。

```
# 開発環境から
$ scp ~/.ssh/id_rsa.pub katryo@1xx.xxx.xxx.xx:~/.ssh/authorized_keys
```

本番環境で、chmodでauthorized_keysへのアクセス制限を600に変えます。

```
$ chmod 600 authorized_keys
```

##日本語localeを作る

ここを参考に。
http://www.compnet.jp/index.php/archives/2571

```
$ sudo locale-gen ja_JP.UTF-8
$ sudo update-locale LANG=ja_JP.UTF-8
```


## ファイアウォールを設定
ファイアウォールを設定します。

CentOSだと/etc/sysconfig/iptablesを編集するんですが、Ubuntuにはufwという便利なコマンドが最初から入っています。

http://d.hatena.ne.jp/babie/20110220/1298181572
http://gihyo.jp/admin/serial/01/ubuntu-recipe/0076
http://linuxsalad.blogspot.jp/2009/02/ufw.html
あたりを参考にして、

```
$ sudo ufw default deny
$ sudo ufw allow 3000 #Railsで使う
$ sudo ufw allow 5000 #Sinatraで使う
$ sudo ufw allow 100022 #port22からsshで使うportを変更した
$ sudo ufw enable
$ sudo ufw status
```

のようにして、3000と5000と10022ポートを開けました。


## add-apt-repositoryがない

初期状態ではadd-apt-repositoryが使えません。
http://stackoverflow.com/questions/13018626/add-apt-repository-not-found
に書いてあるように、

```
$ sudo apt-get install software-properties-common
```

でsoftware-properties-commonを入れれば使えるようになります。

## bind() to 0.0.0.0:80 failed (98: Address already in use)

nginxを起動すると、

```
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()

```

と言われました。

Starkoverflowより
http://stackoverflow.com/questions/14969134/setting-up-linode-ubuntu-10-04-32bit-nginx-not-starting-98-address-already-i
この回答どおり、/etc/nginx/sites-enabled/default を修正して

```/etc/nginx/sites-enabled/default
listen   80; ## listen for ipv4
listen   [::]:80 default ipv6only=on; ## listen for ipv6
```

としたら、nginxが動きました。



## postgresがうまく動かない。
http://tammersaleh.com/posts/installing-postgresql-for-rails-3-1-on-lion

ruby 1.9.3-p327がないと怒られたので、本番環境で

```
$ rbenv install 1.9.3-p327
$ rbenv rehash
$ rbenv global 1.9.3-p327
$ gem install bundler
$ rbenv global 2.0.0-p0
```

とした。


## Nokogiri

libxml2 is missing.  please visit <http://nokogiri.org/tutorials/installing_nokogiri.html>と言われてgem Nokogiri がインストールできなかった。
http://stackoverflow.com/questions/6277456/nokogiri-installation-fails-libxml2-is-missing
を参考に、

```
sudo apt-get install libxslt1-dev libxml2-dev
```

とした。

## PG

gem pgのために、

```
sudo apt-get install libpq-dev
```

もした。ちなみに、
https://wiki.postgresql.org/wiki/Apt
を見てね！　と言われるけれど気にしない。


## Rmagick
rmagickをインストールしようとしたらERROR: Failed to build gem native extensionと言われた。
http://stackoverflow.com/questions/3894225/imagemagick-rmagick-cant-install-rmagick-2-13-1-cant-find-magick-config
を参考にして、libmagickwand-devをインストール。

```
#rmagickのため
sudo apt-get install libmagickwand-dev
```



### SQLite3のアダプター

```
Please install the sqlite3 adapter: gem install activerecord-sqlite3-adapter` (sqlite3 is not part of the bundle. Add it to Gemfile.) (LoadError)
```

と言われた。
http://pgnote.net/?p=2425
より、
database.ymlに書き残していたsqlite部分を削除。


### レポジトリ間違えた
デプロイ用のstoryblog_productionではなく、間違えてstoryblogを設定していたことに気づく。

```config/deploy.rb
set :repository, "git@github.com:katryo/#{application}.git"
```
を

```config/deploy.rb
set :repository, "git@github.com:katryo/#{application}_production.git"
```

に変更。deploy:coldしたら、

fatal: Could not parse object
と言われた。

http://www.willpink.co.uk/post/1074709512/fatal-could-not-parse-object-github-capistrano

のとおり、

```
set :deploy_via, :remote_cache
```
をコメントアウトして

```
#set :deploy_via, :remote_cache
```

としてもよいが、remote_cacheでデプロイできない状況なので、

```
$ mv /app/storyblog/shared/cache-copy cache-copy_backup
```

というように、cache-copyの名前を変えて、いったんデプロイ。
cache-copyが新たに生成される。問題ないことを確認できたらcache-copy_backupを消す。

### therubyracer
libv8のインストールにやたら時間がかかるので調べた。
http://d.hatena.ne.jp/suu-g/20121222/1356189597 より、どうやら原因はコンパイル方法の変化らしい。

```Gemfile
gem 'therubyracer', '0.11.1'
gem 'libv8', '~> 3.11.8.13'
```

としたら速やかにインストールできるようになった。

## Jquery-file-upload

http://railscasts.com/episodes/381-jquery-file-upload/
の通りに作っていたjQuery File Uploadでのファイルアップロードが動かなくなっていた。

jQuery1.9.1ではバグがあるらしい。
https://github.com/blueimp/JavaScript-Templates/issues/19
ので、jQuery-railsを2.4.1にする。

## 

Rails3.2.13での変更によるバグ。
Railscastsのコメントから辿って、
http://railscasts.com/episodes/381-jquery-file-upload?view=comments
たどりついたStackoverflow。
 http://stackoverflow.com/questions/12806230/multiple-file-upload-using-carrierwave-and-jquery-file-upload/15674967#15674967
のように、paramNameを指定した。


## 環境変数
asset_syncを使っていたので、Amazon S3などの外部アプリのパスワード他をサーバに伝えねばならない。

開発環境では.powenvに環境変数を書き込んでいたのだけど、本番環境に送るには？

### 開発環境では
まずはRailscastsの教え通り、application.ymlを作った。

http://railscasts.com/episodes/85-yaml-configuration-revised?view=asciicast 

開発環境で/config/application.ymlを読み込むのは、/config/environment/development.rbに担当させる。

```/config/environment/development.rb
ENV.update YAML.load(File.read(File.expand_path('../application.yml', __FILE__))) if File.exist?(File.expand_path('../application.yml', __FILE__))
```

の行を追加。

### 本番環境では

capistranoでのデプロイ時にもapplication.ymlの環境変数を読み込んで、サーバが動くときにも環境変数を使ってくれるようにCapistranoを設定する。
http://qiita.com/items/7889e0835dfbcc946e57
を参考に、

```/config/deploy.rb
ENV.update YAML.load(File.read(File.expand_path('../application.yml', __FILE__)))

set :default_environment, {
  "AWS_ACCESS_KEY_ID" => ENV["AWS_ACCESS_KEY_ID"],
  "AWS_SECRET_ACCESS_KEY" => ENV["AWS_SECRET_ACCESS_KEY"],
  "GMAIL_USERNAME_DENKINOVEL" => ENV["GMAIL_USERNAME_DENKINOVEL"],
    "GMAIL_USERNAME_KATRYO" => ENV["GMAIL_USERNAME_KATRYO"],
    "GMAIL_PASSWORD_DENKINOVEL" => ENV["GMAIL_USERNAME_DENKINOVEL"],
    "GMAIL_APPLICATION_SPECIFIC_PASSWORD_DENKINOVEL" => ENV["GMAIL_APPLICATION_SPECIFIC_PASSWORD_DENKINOVEL"],
    :FOG_DIRECTORY => ENV["FOG_DIRECTORY"],
    :FOG_PROVIDER => ENV["FOG_PROVIDER"],
    :FOG_REGION => ENV["FOG_REGION"]
}
```

をdeploy.rbの最初に追加。





### Capistranoの設定でport変更
Capistranoの設定でSSH接続するポートを変えられます。
http://d.hatena.ne.jp/tsuyosix/20100514/1273853622
を参考に、

```rb:deploy.rb
set :port, 10022
```

としたら、接続に成功しました。

```
$ cap deploy:setup
```

が動きました。

## DB移行

本番環境サーバ側でもtapsが必要なのでインストール。
ただし、tapsにはpgとsqlite3が必要。そしてsqlite3にはlibsqlite3-devが必要。順番にインストールする。

```
$ sudo apt-get install libsqlite3-dev
$ gem install pg
$ gem install sqlite3
$ gem install taps
```

稼働中のHerokuサーバをメンテナンスモードにする。

```
heroku maintenance:on
```

Herokuからデータベースを取ってくる。

```
$ heroku db:pull sqlite://dump.sqlite3 --app storyblog
```

10000レコードで2時間近くかかった。

開発側にdump.sqlite3がダウンロードできたら、本番環境でtapsのsinatraサーバを稼働させる。

```
# 本番環境サーバ側
$ taps server postgres://storyblog:password@localhost/storyblog_production katryo secret
```

そのサーバに向かって、開発環境側でtaps pushする。

```
# 開発側
$ taps push sqlite://dump.sqlite3 http://katryo:secret@1xx.xxx.xxx.xx:5000
```



## DNS設定

お名前.comで取ってた。
このへん見ながら設定する。

http://akabeko.me/blog/2012/04/revps-06-domain-dns/
http://nomnel.net/blog/set-domain-name/
http://support.sakura.ad.jp/manual/vps/domain/rdns_record.html

5分くらいで、独自ドメインから繋がるようになった。

## Exception_notification

本番環境でサーバエラーが出てもメールで通知されない。おかしいなーと思っていたが、
http://sakura.cb-faq.com/faq/public/app/servlet/qadoc?QID=001401-3
お試し期間中はport 25が開かないのが原因みたい。