CircleCIでinnodb_large_prefixを使う

ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes

と言われた、確かにCircleCIでこれやったことなかったかも。

circle.ymlの中でsudo使えるので、以下のような設定を書いた。

dependencies:
  pre:
    - echo '[mysqld]' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_format=Barracuda' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_file_per_table=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - echo 'innodb_large_prefix=1' | sudo sh -c 'cat >>  /etc/mysql/my.cnf'
    - sudo service mysql restart

[mysqld]はなくてもいい(CircleCIデフォルトの/etc/mysql/my.cnf[mysqld]セクションが最後に来ているため)けど今後に備えて。
;で区切って1行にした方が、build画面が汚れないけど、ここでは保守性を重視。

参考

Premature end of script headers

このブログはPassenger 4上で動いてるんだけど、アプリ側のRubyのバージョンを2.2.1にあげたら、500 Internal Server Errorになってしまった。

エラーログを見ても他に情報がなくて、一瞬困ったが、Apacheデフォルトのエラーログにちゃんと出てた。

passenger Invalid argument - SIGKILL (Errno::EINVAL)

ずばりのIssueが上がってて、Fix済みだった。
Invalid argument - SIGKILL · Issue #1362 · phusion/passenger · GitHub

4の最新版に上げる。
(バージョン指定しないと5になっちゃっていろいろ変わるので注意)

$ gem install passenger -v '4.0.59'
$ passenger-install-apache2-module
# 表示される設定をコピペ。

他のアプリに影響が無いようにPassengerDefaultRubyには今まで使ってたバージョンのRubyを指定しといた。

無事、解消。

Railsのモデルからやむを得ずURLヘルパーを呼ぶ時はprotocolを指定しないとハマる

あくまでやむを得ず。やらないに越したことはない。

root_urlなどを普通にControllerやViewで使う分には、ローカルのhttpな環境で開発してようが、本番のhttpsで運用してようが意識しなくても大丈夫。

が、モデルとかで、

 include Rails.application.routes.url_helpers

みたいに書いて無理やり使ってると、常にhttpが返ってきてハマる。というかハマった。

# 引数で指定
root_url(protocol: 'http')

# デフォルトを変更
Rails.application.routes.default_url_options[:protocol] = 'https'

などの対応が必要。

Ansibleのteamplateでwith_itemsを使う

Ansible: Using item in templates

複数のバーチャルホスト立てる時に非常に便利だった。
confファイルのひな形つくっておいて、{{ item.server_name }}とかで置きかえた設定ファイルを量産していく感じ。

いやぁAnsible便利だなぁ。

Vultrからメールが送れないのでSendGridを使う

Vultr.com Frequently Asked Questions - Vultr.com の通り、デフォルトではSMTPはブロックされてて、解除には写真付き証明書とか必要。
フォーラムでも言われてるけど、ちょっとハードル高い。

というわけで、メール送信クラウドサービスを使うことにした。

メール配信クラウドサービス13個の価格比較グラフを作りました(SES/SendGrid/Mailgun...) - atskimura-memo の通り、いろいろあるけど、SESの次によく名前を聞く、SendGridを選択。

無料枠は400通/日ということで、個人利用ならまず問題なさそう。

設定は、config/environments/production.rbに、

  config.action_mailer.smtp_settings = {
    user_name: ENV['SENDGRID_USERNAME'],
    password: ENV['SENDGRID_PASSWORD'],
    domain: 'example.com',
    address: 'smtp.sendgrid.net',
    port: 587,
    authentication: :plain,
    enable_starttls_auto: true
  }

を書くだけでOK。(Rails 4.1)

最初、

W, [2015-03-11T04:51:09.779586 #10210]  WARN -- : An error occurred when sending a notification using 'email' notifier. Net::SMTPFatalError: 550 Cannot receive from specified address <notifier@example.com>: Unauthenticated senders not allowed

というエラーが発生したけど、Capistranoが古くて、ENVの値が`読めてないだけだった。
Capistranoを3.2.1から3.4.0に上げたら行けた。

参考

Send Email with Ruby on Rails - SendGrid Documentation | SendGrid