Monthly Archives: October 2010

Shibuya.lisp Hackathon #1 に参加しました

以前の会社は9月末で退職したのですが、一番残念だったのはそのとき社内に二人も LISPer がいた1 のに LISP を触らずにやめてしまったことでした。
LISP というか Scheme は以前ちょこっと SICP をやっていたときに触れていたのですが、それきりでした。
今回10/23に Shibuya.lisp Hackathon が開催され、その方たちが参加するということで、LISP を学ぶのにはいい機会だと思って、参加してみました。
結果的には、前職の社員、元社員が一同に介することができて、それもとても楽しいことでした。

Shibuya.lisp Hackathon #1 : ATND

SBCL という処理系をインストールしてある以外、何もわからないので、まず SLIME というものを komagata さんが書かれていた方法でインストール。
SLIME – komagata [p0t]
SLIME: The Superior Lisp Interaction Mode for Emacs

あとは、隣にいた komagata さんの作業を覗いていたり

あたりを写経していました。

なにごとも自分一人だと始めること自体がエネルギーが必要なので、こういう機会があって実際に始めてみられることがよかったです。
謎記号が少しわかるようになったのが嬉しいところです。
今度は 実践Common Lisp を読みたいです。

運営をしていただいた方々、会場を提供していただいたオラクル様、どうもありがとうございました!

  1. というか自分以外 LISPer []

Rails 3 で Paperclip Processor を使用する

Paperclip は高機能なファイル添付のための Rails プラグインです。

thoughtbot’s paperclip at master – GitHub

単純にアップロードが行えるだけではなく、アップロードされたファイルを処理する Processor という仕組みがあります。
Railscasts でも紹介されています。
Railscasts – Cropping Images

この Processor を作成するには Paperclip::Processor というのを継承して、 $RAILS_ROOT/lib/paperclip_processors/hoge.rb みたいな場所に置きます。

この Processor の仕組みが今回必要だったので、 Rails 3 で動かしてみたところ、動いている気配がない。
そこで Processor not loading at first try with Rails3 – Paperclip Plugin というのを参考にして、以下のコードを書いてみたところ無事に読み込まれました。

Hoge::Application.configure do
  config.after_initialize do
    Dir.glob(File.join(File.expand_path(Rails.root), "lib", "paperclip_processors", "*.rb")).each do |processor|
      require processor
    end
  end
end

これを config/initializers/paperclip.rb として置いておきました。

より詳しい Processor の作成方法については以下の blog に非常に詳しく書かれています。
動画をアップロードされたら ffmpeg でサムネイルを作成する方法について書かれていて、非常に参考になります。
Video thumbnails with FFmpeg and Paperclip – Ruby on Rails, JRuby, AWS, EC2, Exalead

注意点としては、 has_attached_file にちゃんと :styles プロパティを設定しておくこと。
これをしないと :processors => [ :hoge ] と書いても、その Processor は呼ばれません。

参考文献

Rails 3 + Haml で production 環境下でもインデントする

Haml をしようするときれいにインデントがされるから好きなんですが、Rails の production 環境下ではインデントがされません。

Haml2.2からはRailsのproductionでインデントが無いと少数派に呼びかけている – komagata [p0t]

速度が問題になるまではインデントしたいので、上記 komagata さんが書かれているように設定したものの、 Rails 3 では上手く動きませんでした。

config.after_initialize でくくらないといけないみたいです。

Hoge::Application.configure do
  config.after_initialize do
    Haml::Template::options[:ugly] = false
  end
end

これを config/initializers/haml.rb に置きました。 1
config/application.rb や config/environments/production.rb の中でもいいですね(たぶん)。

  1. Hoge は適当なアプリケーション名に置き換えること。 []

Ruby 1.9.2 で aws-s3 を使用できなかった問題の解決策

Ruby 1.9.2 が使いたいなぁと思って、いろいろとやっています。
Amazon S3 を使用したいと思って、手持ちの Mac に定番の aws-s3 をインストールして irb で試してみようとするとエラーが出て使用できませんでした。

marcel’s aws-s3 at master – GitHub

ところが Linux ではちゃんと動きます。
特にバイナリをビルドしている様子もないので、こちらの環境が悪いと判断しました。

環境

  • Ruby 1.9.2 on RVM

エラー内容

irb > require 'aws/s3'
SyntaxError: /Users/piyo/.rvm/gems/ruby-1.9.2-p0/gems/aws-s3-0.6.2/lib/aws/s3/extensions.rb:84: invalid multibyte escape: /[
\x80-\xFF]/
        from :29:in `require'
        from :29:in `require'
        from /Users/piyo/.rvm/gems/ruby-1.9.2-p0/gems/aws-s3-0.6.2/lib/aws/s3.rb:11:in `'
        from :33:in `require'
        from :33:in `rescue in require'
        from :29:in `require'
        from (irb):1 
        from /Users/piyo/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `
'

解決策

.zshrc に RUBYOPT=-Ku が設定されていたので、その設定を外しました。

Lokka を nginx + Unicorn で動かす

Lokka は komagata さんが開発されている、Ruby で書かれた CMS です(旧名 Pyhä)。

以前書いたエントリのように、Lokka も nginx と Unicorn で動かしたいと思います。
cocoa*life – Redmine を nginx + Unicorn で動かしてみる

Lokka は Sinatra ベースなので Sinatra で動かすようにすればいいだけのようです。

Unicorn の設定

Lokka のディレクトリに unicorn.rb というファイルを作成しました。
unicorn.rb は前回の使用したものをほぼそのまま使用しました。

# ワーカーの数
worker_processes 2

# ソケット
listen '/tmp/unicorn-lokka.sock'

# ログ
stderr_path 'tmp/log/unicorn.log'
stdout_path 'tmp/log/unicorn.log'

# ダウンタイムなくす
preload_app true

before_fork do |server, worker|
  old_pid = "#{ server.config[:pid] }.oldbin"
  unless old_pid == server.pid
    begin
      # SIGTTOU だと worker_processes が多いときおかしい気がする
      Process.kill :QUIT, File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

Unicorn を起動する

unicorn -c unicorn.rb -D

nginx の設定

nginx の設定は以下のようにしました。

upstream unicorn-lokka {
         server unix:/tmp/unicorn-lokka.sock;
}

server {
        listen  80;
        server_name     lokka.local;
        location / {
                if (-f $request_filename) { break; }
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_pass http://unicorn-lokka;
        }
}

nginx を再起動する。

/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx

参考文献

Redmine を tag ごとに更新する

バグトラッキングシステムの Redmine を運用しています。

Redmine のレポジトリは以下の github で公開されています。
edavis10’s redmine at master – GitHub

ある程度の間隔で更新していきたいところですが、これは trunk なので、これを追っていくのははばかられます。
更新する場合には tag ごとに更新したい。
いまいちどうやってやればいいのかわからなかったので、わかる範囲でやってみました。

タグの一覧は次のコマンドで見ることができます。

git tag

まず公開レポジトリからタグを取得します。

git pull --tags

タグに対するリビジョンを取得します。

git rev-parse 1.0.2
b5cfe790446f9a6bdd968aa65289873f7668f7da

このリビジョンを checkout します。

git checkout b5cfe790446f9a6bdd968aa65289873f7668f7da

2010/11/10 追記
git rev-parse の部分は必要はなく

git checkout 1.0.2

で問題ありません。

参考文献

Lokka で Google Analytics のトラッキングコードを簡単に挿入するための Helper Plugin を書いてみた

Lokka は komagata さんが開発されている、Ruby で書かれた CMS です(旧名 Pyhä)。
打倒 WordPress を目指しているそうです。

komagata’s lokka at master – GitHub

今後使用しようと思っていて、 Plugin も書けるということで、ちょっと試してみました。
簡単に Google Analytics のトラッキングコードが挿入できる Plugin です。

$LOKKA_ROOT/plugin フォルダに hello というサンプルがあるので、それを見ながら書いてみます。
komagata さんのエントリによれば、 Sinatra Extensions のサブセットだということ。

Pyhaの大体の仕組み – komagata [p0t]
Sinatra: Writing Extensions

$LOKKA_ROOT/plugin/ に google_analytics/lib/google_analytics.rb というファイルを作りました。
そして以下を記述。

module Lokka
  module Helpers
    def analytics(uid)
      haml(<<-script, {})
%script{ :type => "text/javascript" }
  :cdata
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', '#{uid}']);
    _gaq.push(['_trackPageview']);

    (function() {
      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    })();
      script
    end
  end
end

モジュール名をどうしたらいいのかわからなかったので、 $LOKKA_ROOT/lib/lokka/helpers.rb を参考に Lokka::Helpers に入れてしまいました。

Rails の感覚だと後は、サーバを再起動すれば動きそうですが、このままでは動きません。
おかしいなぁと思って、プロジェクトを grep してみると、 init.rb にこんな行が。

$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'plugin', 'hello', 'lib'))

これは同じように入れないといけないんだろうかと、こう書いてみる。

$:.unshift File.expand_path(File.join(File.dirname(__FILE__), 'plugin', 'google_analytics', 'lib'))

そしてもう一カ所、 $LOKKA_ROOT/lib/lokka.rb を見てみると

require 'lokka/hello'

なんて行があるので、同様に

require 'lokka/google_analytics'

と書いたところ、無事に動きました。

Redmine を nginx + Unicorn で動かしてみる

今後のために、一度 Webサーバである nginx と Railsサーバ?の Unicorn を使って Redmine を動作させてみることにしました。
すでに Redmine は Apache + Passenger で動いています。

環境

  • Ubuntu Server x86_64 10.04

Rack のアンインストール

このエントリを書いている時点では Redmine は Rails 2.3.5 で作成されていて、 Rails 2.3.5 は Rack 1.0.1 を使用します。
もし Rack の1.2.1とかがインストールされている場合にはアンインストールしましょう。
でないと、こんなエラーが出て起動しません。
これにだいぶんはまりました。

I, [2010-10-05T14:04:25.155622 #26791]  INFO -- : unlinking existing socket=/tmp/unicorn.sock
I, [2010-10-05T14:04:25.155914 #26791]  INFO -- : listening on addr=/tmp/unicorn.sock fd=3
I, [2010-10-05T14:04:25.156344 #26791]  INFO -- : Refreshing Gem list
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.

Unicorn 0.96 doesn’t play nice with Rails 2.3.5

インストール

$ sudo apt-get install nginx
$ sudo gem install unicorn

Unicorn の設定

設定のほとんどは nginx + Unicorn を試してみた – milk1000cc からのコピペです。

ここで設定するソケットを後で使用します。

$ vi $RAILS_ROOT/config/unicorn.rb
# ワーカーの数
worker_processes 2

# ソケット
listen '/tmp/unicorn.sock'

# ログ
stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

# ダウンタイムなくす
preload_app true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{ server.config[:pid] }.oldbin"
  unless old_pid == server.pid
    begin
      # SIGTTOU だと worker_processes が多いときおかしい気がする
      Process.kill :QUIT, File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

after_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

設定ができたら Unicorn を起動します。

$ unicorn_rails -c config/unicorn.rb -E production -D

nginx の設定

http にきたものはすべて https に転送するようにしているので、設定は以下のようになります。

upstream unicorn の部分で設定するものは、先ほどの unicorn.rb で設定したソケットです。
最下行から2行目の proxy_pass で設定する部分は、最上位の upstream hoge の hoge になります。

$ vi /etc/nginx/sites-available/redmine
upstream unicorn {
         server unix:/tmp/unicorn.sock;
}

server {
        listen          80;
        server_name     example.com; 
        rewrite ^/(.*) https://example.com/$1 permanent;
}

server {
        listen  443;    
        server_name     example.com;

        root            /var/www/redmine/public;
        error_log       /var/www/redmine/log/error.log;

        ssl  on;
        ssl_certificate  /etc/nginx/ssl/apache.pem;
        ssl_certificate_key  /etc/nginx/ssl/apache.pem;
        
        ssl_session_timeout  5m;
        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers   on;

        location / {
                if (-f $request_filename) { break; }
                proxy_set_header X-Real-IP  $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_pass http://unicorn;
        }
}

サーバのスタート

$ sudo ln -s /etc/nginx/sites-available/redmine /etc/nginx/sites-enabled/redmine
$ sudo /etc/init.d/nginx start

参考文献