このブログは2015年2月18日に更新を停止しました。すべての記事は https://chroju.github.io へ移行されています。

Railsのデプロイでハマった点まとめ

昨年末に自身初のRailsアプリを見切り発車という名でローンチしましたが、その際デプロイで1か月以上もハマってましたので、ハマリポイントをピックアップしてまとめておきます。

Capistranossh-agentを使う

Capistrano3のタスクの中に、git cloneレポジトリをダウンロードしてくる過程があるのだが、ここではもちろん、GitHub(他のサービス使ってる場合は他の)にアクセスするためのssh秘密鍵が必要になる。ここで利用する秘密鍵ssh先のサーバーに置いておいても良いのだが、Capistrano3ではssh agent forwardingを使えるようにするための設定箇所が存在するので、リモートに鍵をわざわざ転送しなくても、ローカルの鍵が使える。設定箇所はdeploy/(test|staging|production).rbの中で、サーバー設定を書くときに以下のようにforward_agenttrueで宣言すればいい。

server '192.168.1.1', port: 2222, user: 'develop', roles: %w{web app db}, ssh_options: {
  keys: %w(~/.ssh/id_rsa),
  forward_agent: true,
  auth_methods: %w(publickey)
}

サブディレクトリでアプリを展開する場合の環境変数設定

例えば/var/wwwがnginxの見に行くルートディレクトリになっていて、Railsのアプリは/var/www/railsで展開しているというように、サブディレクトリを使う場合はRails側に環境変数RAILS_RELATIVE_URL_ROOTの設定が必要になる。Railslink_toなどを展開してパスを埋め込むときは、このroot設定が元になるので、サブディレクトリを使っていることを環境変数上で明記してやらなければ、本来http://example.com/rails/hogeへのリンクを展開してほしいはずが、http://example.com/hogeが展開される、といったことになってしまう。設定箇所としてはconfig.ruになる。

ENV["RAILS_RELATIVE_URL_ROOT"] = "/rails"

if ENV['RAILS_RELATIVE_URL_ROOT']
  map ENV['RAILS_RELATIVE_URL_ROOT'] do
    run Rails.application
  end
else
  run Rails.application
end

はっきり言ってconfig.ruが何者なのかよくわかってはいないのだが、Rackサーバーを起動するrackupコマンドに起動オプションを渡したりするもの、らしい。そのことについてはconfig.ruの先頭行にコメントでも入っているのでなんとなくわかると思う。が、Rackが理解できてないので結局のところわからない。コマンドは意味から考えれば、Railsを起動するときにパスのマッピングとしてRAILS_RELATIVE_URL_ROOTを渡してやっているように見える。ただ、この書き方だと環境変数の宣言をconfig.ruの中で行った上で、その環境変数の存在をifで確認するというちょっとマヌケなロジックになってしまっているので、おそらくは環境変数を別のところで宣言するのがベターなのだと思う。

なお、サブディレクトリでRailsアプリを立ち上げるには、ウェブサーバー(nginx + unicorn)に対しても設定が必要だが、ここでは割愛。nginxのlocationディレクティブを使う、とだけ覚えておけばなんとかなるはず。

参考

assetsに対するルーティング設定

assets:precompileを使ってあらかじめassetsフォルダ内にcssとjsを展開していたのだが、ブラウザ経由でいざアプリにアクセスすると、CSSJavaScriptも適用されていない(assets配下が読み込めていない)という事象が発生した。

原因はルーティングが正しくなかったから。前述の通りExhiBiでは/var/www/railsにアプリを展開していたのだが、さらに細かく見るとrailsフォルダの中にはreleasescurrentsharedという主に3種類のフォルダが配置される。releasesは要するにgit cloneの対象フォルダで、ソースコードCapistranoで宣言した数だけバージョン管理している。sharedはbundleやlogといった、リリースバージョンに左右されず不変のファイルを格納する場所で、Capistranoで言えばlinked_dirsにあたる。この2つのフォルダをcurrent配下にシンボリックリンクすることにより、currentが実際のアプリ配置場所として機能する。従ってnginxのlocationディレクティブはこんな感じになる。

location /rails {
  alias /var/www/rails/current;
}

ここでassetsへのルーティングを考えてみると、assetsに対するパスはhttp://example.com/rails/assets/hogehogeになるため、/var/www/rails/current/assetsを見に行くことになる。しかし実際にはassetsはshared/public/assetsであり、シンボリックリンクcurrent/public/assetsに貼られている。そのため先のlocatonだけではassetsに到達することはできないため、assets用のlocationディレクトリが別途必要になる。

location ~ ^/rails/assets/(.*) {
  alias /var/www/rails/current/public/assets/$1;
}

参考

SECRET_KEY_BASEの環境変数設定

ブラウザ経由でアプリにアクセスしたら、404ではないのだが画面が真っ白になってしまう事象。ぐぐってみるとドンピシャすぎる記事があって大変助かった。

SECRET_KEY_BASEという環境変数を設定してやらねばならんらしい。なんじゃそりゃ。環境変数の設定なので方法は下記のURLのようにいくつかあるみたいだが、自分は取りあえずChefレシピの中で、.bash_profile環境変数設定をいれこむことにした。これも何かしらベストプラクティスがありそうな気がする。。

参考

gem 'pg'が入らない

入らない。なんか知らんが入らない。ググるとどうも入りづらいGemの筆頭である模様。いろいろ探って、therubyracerを先に入れるべきだと聴いてやってみたけど結局入らない。とにかくどうやっても、Capistranobundle installMake sure that gem install pg -v '0.17.1' succeeds before bundling.と言われてしまう。仕方ないのでsshでサーバーに直に入ってbundle installを手動実行してみるとなぜか入る。わからん。これだけは本当にわからん。さらにその後はtiltが入らないとか言われたりもした。ソースをrubygems.orgから変えたりしてなんとか入ったのだが、ちょっと腑に落ちない感。

参考

posgresqlのユーザー管理

SQLに関する基礎知識のなさを猛省した。とりあえずわかってなかったのこんなとこ。

  • pg_hba.confで指定できる認証方式でmd5はパスワード認証、peerはOSにログイン中のユーザー名でログインしようとする
    • よってsqlで使う予定のユーザー名がOS側に存在しない場合、peerを使おうとするとコケる
  • psqlコマンドでログインしたとき、まずユーザー名と同名のDBにアクセスしようとするので、それが存在しないとエラーになる
    • でもDB作成ってrake db:createでやると思うんだけど、このコマンド打つときはどうやってアクセスするの?あれ?
  • DBに初期データを投入したい場合はdb/seeds.rbに書いてrake db:seedを打つ
  • rake db:migrateはテーブル生成だけでデータ登録までは賄ってくれない
  • 開発段階でmigrateファイルをやたらと作ってたりすると上手くdb:migrateできないこともあるので、整理した方がいいかも

参考

RailsCapistranoのいずれも抽象度の高い技術で、これは何度かブログに書いてきてるけど、その内実をきちんと押さえてないとエラーが起きた場合に結構辛いことになる。READMEを読むこと、公式のWikiなどがあるならそっちも目を通すこと、エラーが起きたらログを見ること、あるいは前もってログを吐く設定にしておくこと。このあたりは改めて徹底したいところ。

あとここからは余談だが、Railsのデプロイ先としてherokuが好まれるのは、ある程度「間違いのない選択肢」ということなのだろうなと想像している。ここで自分がつまずいたサブディレクトリでのアプリ展開や、postgresqlのコンフィグなどは、herokuであれば必要がなくなる。一旦用意されている高速道路を全力で走ってみて、それが成功してから自分好みに変えていく方が近道なのかもしれない。なんとかしてposgresqlを使おうとこだわったり、サブディレクトリでの運用をさせたり、最初からいろいろ欲張りすぎた点も反省。

美術展検索サービスExhiBiを見切り発車しました

ExhiBi

初めてウェブサービスをローンチしました。ネタとしてはすでにゴマンとある美術展の検索サービスです。既存のものがあんまりしっくりこなかったので、自分向けに対象を絞って、掲載情報も絞ったものを作ろうかと。ただし現時点だと絞りすぎてまだ出来てなくてMOTとMOMATしか範囲に入ってないッス。タイトル通り超見切り発車。なおExhiBiと書いてエキシビと読みます。

技術的な面では自分が「コードを書けないエンジニア(GUIによる設定ばかりに従事しているインフラエンジニア)」なので、何かしら書けるようになりたいよねということで、汎用性も高そうで文法的にもしっくりきたRubyを選びました(細々した理由は他にもいろいろとありますが……)。フレームワークには当然のごとくRails、中身のデータはMechanizeで美術館サイトから取ってきてます。あとはInfrastructure as Codeを意識したかったので、ChefとCapistranoを軸に構築してます。若干手作業が残ってしまったのが気掛かりなので、後々なんとかしたいところ。

しっかしRailsのデプロイ、めっちゃめちゃハマりポイント多かったんですがなんなんですかね……。開発自体は半月で終わったけどデプロイで1か月以上苦しんでました。自分が単に知見がないってだけの話なのか、元々そういうものなのか。オライリーもRailsのデプロイだけで1冊出してるぐらいなので、結構難しいものなのやも。

今後やりたいことは取りあえずこんな感じ。

  • 対象美術館を増やす
  • 気になる展覧会をクリップしとく機能
  • 気になる美術館を同上
  • レスポンシブ、とかデザイン面をもうちょっと
  • コードきたねーので整える
  • はてなブログのembed記法に対応させる(冒頭のリンクだとなんかダサい)

コードは一応GitHubに上げてますが、場当たり的に直しちゃったところもあるんで汚いです。ていうか仕事でコード書いたことないからもう少し作法とか身につけたい。

なんとか年内にあげようと思ってたんで、間に合ってホッとしました。技術的な話はおいおい少しずつブログにまとめていきます。

『インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門』読了

インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門
みやた ひろし
SBクリエイティブ
売り上げランキング: 9,418

去年の末ぐらいに話題になってた本だと思うけど、読み終えた。よかった。

自分はネットワークスペシャリストを持っているんだけど、IPAの資格って基礎を満遍なくさらっておくには良いんだが、じゃあその知識の中で今現場で必要なのどれよ?ってのがなかなかわかりにくい面がある。この本はその「現場で実際どうネットワークは組まれるのか?」という部分に大きく焦点が当たっていて、知識を実践的なものに洗練できる。L3をコアスイッチにして構成していくのが主流ですみたいな話から、ケーブルにタグ付けてこういう情報書いておきましょうなんていう細かいことまで載っていて隙がない。

こういうことができる/できないという知識があったところで、じゃあそれがネットワークを組む上でどう活きるかというのはまた別の話であって、そこを弁えてないと車輪の再発明に手を煩わせてしまったり、組んだ構成が主流から外れてたりということはままある。自分がまさにそういう状態で、ベストプラクティスをきちんと押さえていないことがずっと気がかりだったので、今ネットワークを触る上でベターなやり方、注意点を体系的に学べたのはとても良かった。知識レベルとしては応用情報技術者があれば読めるレベルだと思う。1〜2年目ぐらいでネットワークに携わり始めたぐらいの社員が読むには本当に優れた1冊です。

ブログ書けてない不安

インプットに対してアウトプットの量が少ないなと前から思っている。ブログを書いてるとアウトプットの履歴が残るから「アウトプットしてない」時期が明確にわかり、それを見て不安になったりもするんだけど、結局書けてない、ということが続く。

何かコーディングするときや構築するとき、わからないことがあるとついついググって探して実装して、そのままにしてしまうことが多いんだけど、これだと一過性で終わってしまって、結局記憶に残らず終わったりする。せめてはてブしたりEvernoteクリッピングしたり、ぐらいはするときもあるのだが、これはこれでクリップしたまま記憶の底に埋もれていくので、やっぱり身になった気がしない。きちんと知識の定着を図るなら、何度も繰り返し試してみるか、インプットした内容を頭の中で咀嚼して、その経緯を自分なりにアウトプットし直すのが一番いい。

なんで書けないのか?というと怠惰という理由が最も強いように思う。特に壁にぶつかったときは山のようにググって比較検討して答えを見つけようとしてしまうから、結局どのページを見て正答に至ったのかが曖昧になったりしやすい。まずは公式ドキュメントにあたるだとか、試行錯誤した結果でさえ一つ一つ丁寧にログを残すだとか、そういうことをできていない。

ちなみにメモツールとしてはアナログだとモレスキンのラージ、デジタルだとVimプラギンのQfixHowmを主に使っている。QfixHowmを使っているのは正確にはプライベーとのPC上だけで、要はDropboxにプレーンテキストでメモを書き溜めている形になる。アナログについては、先月までは常に1日1ページ手帳のEDITを携えてメモ代わりに使っていたんだけど、ページが足りなくなることも多かったし、そもそもスケジュール管理はGoogle Calendarに全部移行していたので、もう手帳を持つ意味もないなと思い、自由度の高いモレスキンに変えた。職場の関係でDropboxは使えないし、ノートPCを叩きながら打ち合わせに臨むのも好ましいとされていないので、アナログのメモはどうしても捨てられずにいる。あと思考を巡らせるときなんかには自由度の高いフォーマットの方が好ましくて、iPad miniタッチペンとか使うよりも広めのノートの方が脳と手が直結しやすくて楽。

基本的にはこれらに「なんでも書く」方針でいるのだが、散漫な思いつきなどは書けていても、本を読んだり勉強しながら書く習慣がない。tmux開いてコーディングして、ウィンドウを切り替えてメモしてという手順を踏めばいいはずなんだけど、ついつい怠ってしまう。プログラマーの三大美徳に「怠惰」が含まれてはいるが、究極の怠惰は生産性を持たないものだと思う。

書くためにどうしたらいいのか?という問いに対する答えは自分でもまだ見出だせていない。こういうのはもう性格レベルの問題なので、「意識する」とかそういう類の対策じゃなんの意味もなくて、もっと根本的にメモせざるを得ない状況を生み出すしかないのだと思う。あるいはメモの効用をより強く自覚すること。怠惰とはいえ、本当に必要だと思っていることはそれなりにこなせてはいるので、メモを書いてないことで痛い目見るような経験がもっと増えれば変わるような気はする。

Rakuten Technology Conference 2014に行ってきた

イベント終了から1週間後にレポートとか遅すぎますね。これの前の週のオープンソースカンファレンスがせっかく土日開催だし行こうかなと思っていたんだけど、土曜に徹夜仕事があったんでさすがにしんどくて行けなくて、じゃあこっち行こうかな、と行ってみた具合。

中嶋聡氏→三木谷氏→OpenStackの話→Matz氏→Chefの中の人という大変ミーハーなタイムテーブルで回ったけど、著名なハッカーの話を聞く機会というのは何度か設けておくべきなんだろうと思う。当然ながらウェブや雑誌で何度も著名な人の話は読んでいるわけだけど、実際目の前で話してもらうと記憶への残り方とか、影響の受け方とかやっぱし違ってくる。

エンジニアとしての哲学

特にMatz氏の話を聞いていて思ったのが、エンジニアとして哲学というか思想というか、そういうのはきちんと持っておきたいなということ。

エンジニアというのは知的生産、クリエイティブワーカーだという人もいるが、意識によっては単なる流れ作業の駒になりかねない。実際、自分の今の仕事というのはそちらに近くて、顧客からの要件をいかに盛り込むか、いかに期日までにリリースして検収をもらうか、というところにばかり目がいってしまっていて、全体のデザインが出来ていないことはままある。短期的に売りを上げるだけであれば別にそれでいいのだが、思想のないシステムは運用上のトラブルが多いだとか、更改や拡張に対する思慮に欠けているだとか、長期的には利を失うことにつながりやすい。

キャリアデザインとしても、思想がないエンジニアはブレる。というか、単に売り上げて金回すサラリーマンエンジニアになりたいのか、それともいわゆるハッカーとしてやっていきたいかの境界線の一つがそこなんじゃないかなと。どちらが良し悪しではないし、どちらでも人生で「やっていく」上では困りはしないとは思うのだが、どちらが自分にとって楽しいかが問題だ。自分は結構収入面って後回しに考えていて、自分が思うような価値を生み出せる人間になれればいいと思うし、その対価として金が得られればそれでいいのかなと思う。

リクルーティングとしてのイベント

いろいろと縁があって、ビジネス的なつながりがない企業の中では楽天がおそらく一番多く訪問してるんだけど、今回はだいぶ中の方まで入り込めて、ちょっとだけ実態が理解できたように思う。噂の楽天ランチは大変楽しみにしてたのだが、思ってたより薄めの味付けで社員の健康を考えている会社って素晴らしいなぁと感心してしまった。でもその後、カフェテリアで開かれる午後のセッションに行ったら無料でピザやらポテトやら唐揚げやらコーラやら配られてたんで、「あかん、これ罠や」と思いました。

あと周知の通り社内は英語公用語化していて、イベント自体も英語が基本なんだけど、実態としては会場内の案内は日本語遣うスタッフもいたし、本当に英語しか喋らない外人スタッフもいるし、日本語喋る外人スタッフもいるしでわりと脳味噌混乱した。参加者側も外国籍の人が半分ぐらいいたんじゃないかという感じ。

こういうあたり、単純にエンジニアイベントというよりは、楽天という会社の在り方をアピールする機会として本当にうまく活かしていたなと思う。夜のBeer Bashの裏でHiring Partyも開かれているのはちょっとびっくりしたけど。

『実践Vim』でVimの思想を身につける

何ヶ月か前にKindleアスキー本のセールをやっていたことがあって、そのときに買ったのをやっと読み終えた。技術書を電子書籍で読むというのは、感覚の問題なんだけどどうも身が入らない。ドッグイヤー付けたりとか書き込んでみたりとか出来なかったり、あるいは満員電車の中とかでも手軽に読めすぎてしまって、腰を据えて勉強する感覚がなくなるからなのかなぁという気がしている。なお、これまでKindle読むのにはXPERIA Z1fを使っていたが、さすがにしんどくてiPad miniを買った模様。もちろん、他にも理由はあったけど。

自分はVimを使い始めて1年ちょいというところで、これまでVim本をきちんと読んだことはなかったのだが、読んでよかったと思う。

Vimの情報はネットにありふれすぎていて、素のVimから触り始める人ってあんまりいないような気がする。自分も最初からKaoriya版を使っていたし、使い始めてまもなくGitHubやQiitaから他人のvimrcを拝借してきて、NeoBundleでプラギン入れて使っていた。特にプラギンまわりが楽しすぎて、ほうほうVimはこんなことができるのかー!とwktkしながら1か月ぐらいはvimrc触りまくってたように思う。自分のGitHub見るとまーよくわかる。

でもこの本にも書いてある通り、まずは素の状態で試してみるべきなのだ、本来。Vimは最初からできることが豊富にある。テキストを扱う上で必要な操作がいくらでも揃っているので、まずはそれらを味わってみて、足りなければvimrcで味付けしていけばいい。そうじゃないとVimの設計思想というか、Vimによってテキストをどう扱うべきなのかという原則論が見えてこない。

本書はプラギンの話は皆無で、Vimが最初から備えている機能を中心に解説されている。.を始めとした繰り返し操作を多用する考え方だとか、テキスト対Vimというありがちな考え方だけではなく、ファイル対Vimという考え方もしなくてはならないとか、学べることは本当に多かった。あまりに分量が多いので一気にすべてのことを実践できるわけではないが、これはと思ったとこから取り入れていきたい。おそらくVimツールではなくて思想なのだ。親指シフトHHKBなんかと同じように、最速でテキストを編集するための思想。もちろんここでいう「Vim」には「Emacs」も当てはまってくるのだろうけど。あと正規表現ちゃんと覚えなあかんなと思った。後半の検索、置換のあたりは当然ながら正規表現を使える前提の話が多くて、きちんと使えてない自分には少ししんどかった。

awesomeウィンドウマネージャーの見栄えを良くする

Arch Linuxで使っているデスクトップマネージャ、awesomeのテーマに若干手を入れてみたので備忘録。あんまり日本語ドキュメントないので、このあたりのカスタマイズしんどかったです。

テーマファイルの構成

awesomeの設定はいくつかのLuaファイルを使って書き換えていく。基本的には全体設定を司る~/.config/awesome/rc.luaと、外観やテーマを司るライブラリである、Beautifulの設定ファイル~/.config/awesome/themes/default/theme.luaの2つを覚えておけばいいのかなと。いずれも初期状態では配置されてないので、デフォルトファイルをコピーしてきて使う。

# cp /etc/xdg/awesome/rc.lua ~/.config/awesome/rc.lua
# cp -r /usr/share/awesome/themes/default ~/.config/awesome/themes/default

Beautifulについてはrc.luaの中で設定ファイルのパスが指定できるので、defaultという名前が嫌だったら任意で変えてもOK。あとは正直awesomeのWiki見るのが手っ取り早いとは思うのだが、設定したところだけ書いておく。ちなみに前回記事で書いたが、awesomeのデフォルトターミナルの設定もrc.luaを使うので、外観変える必要なくてもrc.luaだけは確実に要ると思う。

タグリストの書き換え

awesomeでは仮想デスクトップを"tag"と呼んで扱っていて、デフォルトの状態だと左上に1から8まで(だったかな?)の数字がタグの番号として並んでいる。あまりわかりやすいものではないし、そんなに多くタグも使わないので書き換える。

tags = {}
for s = 1, screen.count() do
    -- Each screen has its own tag table.
    tags[s] = awful.tag({ "Firefox", "Terminal", "Vim", "other" }, s, layouts[1])
end

あとウィンドウを開いているタグは小さな正方形が表示されたりしていて鬱陶しかったのと、あまり見栄えも良くなかったので、正方形を表示されないようにした上で、フォーカスしているタグは文字色を変えることにした。これはbeautifulの方で設定する。

theme.taglist_fg_focus = "#f15c22"
-- theme.taglist_squares_sel   = "/usr/share/awesome/themes/default/taglist/squarefw.png"
-- theme.taglist_squares_unsel = "/usr/share/awesome/themes/default/taglist/squarew.png"

1行目がフォーカスされているときのfg、フォアグラウンドカラーの設定。2、3行目はデフォルトで入ってる設定だったのでコメントアウトしておいた。

ウィジェットの表示

画面上の情報表示はウィジェットとして扱う。ウィジェットを管理するライブラリはいくつかあるみたいなんだが、取っつきやすそうなので自分はviciousrc.luaの中でrequireして使っている。

$ yaourt -S vicious

インストールした上で、

local vicious = require("vicious")

設定の順序としては、awesomeがもともと備えているウィジェット生成用のAPIであるwiboxを使ってウィジェットのの原型をセットし、これにviciousを使って表示させたい情報をセットする。ここではバッテリー状態と音量、Wi-Fiの状態を表示させる。どんな情報を表示させられるのか、詳細はここ

--
battxtwidget = wibox.widget.textbox()
vicious.register(battxtwidget, vicious.widgets.bat, " Battery: <span color='#ffffff'>$2%</span> ", 60, "BAT0")
--
soundwidget = wibox.widget.textbox()
vicious.register(soundwidget, vicious.widgets.volume, " Vol: <span color='#ffffff'>$1</span> ", 2, "Master")
--
wifiwidget = wibox.widget.textbox()
vicious.register(wifiwidget, vicious.widgets.wifi, " Wi-Fi: <span color='#ffffff'>${ssid}</span> ", 60, "wlp1s0")

ウィジェットを作ったら、画面上のレイアウトにウィジェットをセットする。

-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
-- if s == 1 then right_layout:add(wibox.widget.systray()) end
right_layout:add(soundwidget)
right_layout:add(battxtwidget)
right_layout:add(wifiwidget)
right_layout:add(mytextclock)
right_layout:add(mylayoutbox[s])

自分がした設定はこの程度。あとはbeautifulでtheme.font = "sans 10"の設定でフォントサイズを少し大きくしたぐらいだが、beautifulの設定ファイルを見ればわかる通り、かなり細かく色やら何やら設定ができる。このへんに凝り始めるとキリがないので自分はやめることにしたが、好きな人はやってみたらいいんじゃないですかね。1つ、GitHubですげーカッコイイテーマ配ってるの見つけたんで貼っときます。Samuraizuとか思い出すなー。