is Neet

ネトゲしながら暮したい

友人が作ったベーコンを頂いた

f:id:soplana:20140804084234j:plain

割りと長い付き合いになるネトゲ友達がいて, 彼が自宅の庭に燻製用のナニカを作ったらしい.
ベーコンやらウィンナーやらを沢山作っているっぽくて, おすそ分けしてもらった.

彼は福岡にいるんだけど, ベーコンと一緒に明太子とかポテチの九州しょうゆ味とか送ってくれて福岡に親戚ができたようでテンションあがって, こっちからも何か送るかと考えたけど, 東京ってこういう時困るよなと思った.
なに送ろう?

f:id:soplana:20140804084220j:plain

ベーコン, 1kgも送ってくれて消費しきれないかもと不安になっていたけど案外コンスタントに食べてたら一週間ちょっともあれば消費できそうな量で安心した.
単純に何も調味料つけずに焼いて食べてもしっかり味がついてて歯ごたえもあってめちゃくちゃ美味しいし, 最近は毎朝目玉焼きと一緒に食べてて最高の人生っぽくなってる.

そういや一緒にやってたネトゲでも彼は生産職をやっていて, 彼は当時僕よりずっと高レベルだったので初期に必要な回復アイテムなどを大量に作って頂いたりしていたし, ネトゲもリアルもやっぱり人間性出ていいなと思った.
僕は当時ゲーム内や2chの某ネトゲスレで迷惑行為をひたすら繰り返してたんだけど今は随分落ち着いた.
あの頃もニートだったなー.

株式会社ジモティーを退職して光の戦士になりました

2年ちょっと働いていた会社を9月いっぱいで退職した。
流行りの退職エントリーを書けるので嬉しい。
特に内容は濃くない。

ニートからジモティーに入社

それまでニートしてた。
シコシコwebサービス作ったりrails勉強してたりしたこともあり、運良くジモティーで拾ってもらい就職。
最初の大きなミッションは、α版として公開されていたサービスを1から全部作りなおすこと。
僕が入社した時、4人の優秀なエンジニアがすでに社員として働いており、彼らに色々教えてもらいながら何とかサービスのローンチを経験させてもらった。
クソ忙しかったけど、正直この時が一番楽しかったかもしれない。
それで出来たサービスがコチラ↓

今すぐ掲載!地元で探す掲示板 ジモティー

退職までの二年間

ジモティーは所謂スタートアップ系に分類される会社なので、結構なんでも自分達でこなさないといけなかった気はする。
サーバ・インフラ周りやクライアントサイド・デザイン、速度改善などサービスの成長に合わせて問題にぶち当たり、その都度自分たちで色々調べたり、時には外部の優秀なエンジニアに助けてもらったりしながら「サービス運用とは」みたいな所が学べたように思う。
そういったエンジニアとしてのスキル以外も、本当に優秀なビジネスサイドの方々から資金調達の事であったり株式の事であったり、仕事の進め方、ビジネスの考え方、サービス設計など多くの事を教えていただいた。

一緒に働けたエンジニアはみんな優秀でそれぞれ得意分野が違ってたくさんの事を学ばせて頂いたし、自分も大概プログラミング好きな方かと思っていたけど彼らと比べると、全然そんなことなかった事実をつきつけられて死にたくもなった。
とにかく色々と勉強になる2年だった。

なんで辞めるの

FF14が発売され、エオルゼアという世界が危機に陥っている事を知った。
エオルゼアは第七霊災からの復興、蛮神問題など多くの問題を抱えてる。
ある日僕はエオルゼアを冒険する中で、黄金の鉄の固まりである自分がエオルゼアを救う光の戦士だと言うことを告げられる。
これはリアルなんかに現を抜かしてる場合ではないと気付き、次の日には退職を申し出てた。
要約すると、ニートに戻った。ニートしたかった。

これから

少なくとも年内はちょこちょことジモティーや他社を手伝ったりしつつ、ゆっくりする予定。
来年くらいからまた人生について考えよう。
失職祝いに焼き肉でもおごってやるよって方は@soplanaまでメンションくれ。
もしくは可愛い♀ミコッテがいればハデス鯖で遊んで下さいお願いします。

ジモティーがエンジニアを募集してるっぽい

してるっぽい。
軽く僕が思うジモティーで学べる事学べない事に触れておくので、これをみて興味があれば@soplanaまでメンションしてくれればフォローするのでDMでも。

Rails 3.1で画像ストレージにAmazon S3を使う

僕が趣味で開発&運営しているラクガキサービス「Leeno」の画像ストレージを、s3へ移行しました。


まずLeenoの構成は以下。

  • VPS:さくらのVPS 1.5Gプラン(今はもうないけど)
  • OS:Fedora
  • リバースプロキシ:Nginx
  • appサーバ:unicorn
  • 言語:Ruby( on Rails 3.1 )
  • DB:MongoDB

といった具合。



s3へ移行前のLeeno

Leenoは画像をメインのコンテンツとして扱うサービスです。
今回S3に移行するまでは、MongoDBのGridFSという巨大ファイルを扱うためのストレージを使っていました。
まずUploadの流れですが、これはとてもシンプルで、

  • html5canvas要素からbase64エンコードされた文字列を取得
  • jsでサーバに送信して、受け取ってデコードしてふごふごする
  • ふごふごしたデータをGridFSに突っ込む


で、表示のさいはRailsのactionで

def image
  send_data( @history.to_image, :disposition => "inline", :type => "image/png" )
end


といった具合で、画像データを返すactionを用意しておいてView側で

image_tag( history_image_path(@history.to_params_key), options )


みたいに使っていました。
しかしまぁこのままでは、画像データにアクセスするたびにRailsのaction通るわ、GridFSから画像読んでくるわで効率悪すぎワロタ状態なので、Railsのcache機能を使いcontrollerで、

caches_page :image

という宣言をしておきます。
これで一度誰かが閲覧した画像は、Rails.root/public/以下にキャッシュが残っていくので、次回移行のアクセスの場合はRailsのactionを通る前にpublic以下を見てファイルが存在すればそのままそれを返却してくれるようにしておきます。


一応この構成でも満足な速度は出ていたのですが、大きな問題点がありました。

  • まったく冗長化されていいない。GridFSのファイルが何らかの障害で壊れたらおしまい。
  • public以下にキャッシュしているとは言え、多い場合は1ページに100枚以上の画像を読み込むので、その分リクエストはサーバに飛んでくる
  • Railsのpublic以下にキャッシュするということは、いずれwebサーバが複数台にまたがった時に破綻するキャッシュ方法だということ

とくに一番目が心配でした。



Amazon S3を使うと何が嬉しいか

  • まず冗長化ハンパない。

 データの保存と同時にS3作成したリージョン内で物理的に違うサーバ複数台でレプリケーションしてくれる。
 その冗長化に喪失があればすぐに検知して修復してくれる。
 つまり東京リージョンで作成した場合、東京が一瞬で消滅しない限りLeenoのデータは安心。堅牢性ヤバい。


  • リクエストがleeno.jpサーバに飛んでこない。

 全部S3に直リンしてるからウチのサーバが悲鳴あげる事ない。


  • スケールアウトしやすい

 いずれwebサーバが複数台にまたがったとしてもデータはS3上にあるので無問題。


と、良いことばっかりな気がするので移行しました。




S3にバケットを作成する

AWSへの登録とかは端折ります。
S3ではまずBucketを作成し、そのBucketにオブジェクトを保存していく流れになります。
まず、AWS consoleに入りS3タブを選択しCreate Bucketを押します。


f:id:soplana:20120524003652p:plain


そうするとポップアップが開くので、適当にBucket名を入力し、RegionはTokyoを選択しCreateします。

f:id:soplana:20120524004216p:plain


以上でBucketの作成が完了しました。お早い。



Railsから保存する

まずS3を扱うためのGem入れましょうね。
お手元のGemfileを開き、

gem 'aws-s3', :require => 'aws/s3'

を追加して、bundle installしてください。


次に、S3へアクセスする為のキーを取得します。
AWS consoleに入り、右上のアカウントメニューから、Security Credentialsを選択ます。

f:id:soplana:20120524004845p:plain


そしたらアクセスキーとシークレットアクセスキーが取得出来るのでメモっとておきます。

f:id:soplana:20120524004914p:plain



以降、Leeno仕様で話を進めます。
LeenoはCanvasというcollection(RDBでいうテーブル)があり、Canvas collectionはhas_manyでHistory collectionを持ちます。
誰かが一枚目にラクガキを書いた時にCanvasが作成され、そこにはCanvasの作成者やサイズなど基本的なデータを持ち、Historyが具体的な画像データなどを持っています。


なので今回、画像を保存するといった処理もHistory Classが管理する仕事なので、History Classにincludeしたらそれっぽく使えるmoduleを簡単に作成しました。こんな感じ。

module LeenoS3
  BUCKET = "leeno"
  
  # moduleをincludeした時にAWSの設定を実行する
  def self.included(model)
    # メモっておいたアクセスキーとシークレットアクセスキーを設定
    AWS::S3::Base.establish_connection!(
      :access_key_id     => 'xxx', 
      :secret_access_key => 'xxx'
    )
    # gemが東京リージョンに対応してないらいので設定
    AWS::S3::DEFAULT_HOST.replace "s3-ap-northeast-1.amazonaws.com"
  end

  # accessの範囲をpublicに設定してあげないと外部から見れない
  def upload file_name, file 
    AWS::S3::S3Object.store(file_name, file, LeenoS3::BUCKET, :access => :public_read)
  end

end


あとは、Base64エンコードされた画像データとファイル名をふごふごしてuploadメソッドに渡すと保存完了です。
ちなみにファイル名は"hoge/sample.png"とファイルパスで渡すと、S3上にもそのディレクトリが出来上がります。


View側で呼び出す時は、History Classにto_image_urlみたいなメソッドを定義して、S3へのURLを取得できるようにしておき、

image_tag( @history.to_image_url )

といった具合に、リファクタリングしました。


問題なのはLeenoにはRedrawという、他人が描いた絵にラクガキ出来る機能があります。
処理的には、

  • Aさんがhoge.pngというラクガキ画像を作成。
  • hoge.pngがleeno.jp(GridFS)に保存される。
  • Bさんがhoge.pngを元に新しいラクガキ画像を作成しようとする。
  • GridFSにアクセスして、hoge.pngを取得してHTML5canvas要素にdrawImageメソッドを使い描画する。
  • Bさんがラクガキしてサブミットするとhoge2.pngがGridFSに保存される。


となっていたワケですが、canvas要素の仕様で外部ドメインの画像は直接扱えません。
今まではleeno.jp(GridFS)から取得していた画像だったので、問題なくRedraw出来ていたのですが、S3へ移行すると外部ドメインになるので、Redrawが出来ないといった問題が浮上しました。
なのでRedraw用の画像を取得するactionを少し改修して、

def redraw_image
  send_data( @history.to_image, :disposition => "inline", :type => "image/png" )
end

となっていた所を、

def redraw_image
  send_data( open(@history.to_image_url,"rb").read, :disposition => "inline", :type => "image/png" )
end

というふうに、一度open-uriでS3の画像を開き、それをsend_dataで返す事で、leeno.jpの画像のように見せかける事にしました。


だいたい以上で、移行は終了しました。

現在Leenoは約7000枚程画像があるので、それらをS3にアップロードするスクリプト書いて終了です。




Nginxの一時ファイル保存ディレクトリの所有者変更(5/24追記)

ところが本番リリースしたあと、画像データを半分くらいまでしか読み込まないという問題が発生しました。
Nginxのログを確認した所なにやら見慣れぬエラーが。

2012/05/23 02:25:52 [crit] 21236#0: *66652 open() "/var/lib/nginx/tmp/proxy/9/63/0000000639" failed (13: Permission denied)

どうやらopen_uriを使って取得したデータをsend_dataしてる部分で、一時的にファイルを保存してるみたいなのですがその保存先のディレクトリに権限がなくてエラーになってるようです。
なのでNginxを起動しているUserに所有者を変更してあげれば、この問題は解決しました。
だいたいPermission deniedなのに何で画像の半分くらいは読み込めたのかは謎なのですが。
原因究明してくれた@T_Hash先生に感謝。




S3凄い! でもお高いんでしょう?

気になりますよね。値段。
取り敢えず現段階での話になるのですが、大体一日で、$0.19でした。
ただ、S3の従量課金はPOSTの方が高めに設定されていて、この日は7000枚の画像をS3にアップロードした事もあり、かなり高めになっていると思います。
$0.19 = ¥16だとすると、仮に¥16/日だとしても¥16 * 30 = ¥480となります。
7000枚アップロードしてこれなので、かなり良心的な値段設定なのではないでしょうか。
アクセス数やPOST数が10倍とかになると¥5000/月なのでそこそこかかってしまいますが。

                    • 6/1追記-------------

S3に乗り換えて10日ほど経ちましたが、現在$0.23でした。
一日$0.01以下で済んでいるので、アホみたいに安いです。ビビった。安すぎる。


まとめ

移行の手間もそんなにかからなかったし、値段も良心的だし、今のところ移行してよかったなと感じております。
ここからさらにCloudFrontとかを立ててキャッシュを効かせたりすると、さらに効果的だったりするようですが、それはまだ対応していません。
cssやjs等のassetsファイルだけCloudFrontに置いてアクセスの高速化を測る、などといった使い方も出来るのでLeenoもそのうち導入しようかなーとは思っています。


おしまい。

Twitter Botを、RubyとMongoHQを使って作ってみたのでまとめておく

Bot作ってみました。

f:id:soplana:20120330000208p:plain



知り合いからリクエストがあったので、Rubyで「あまえびたん」というTwitterBotを作ってみました。
仕組はとても単純で、「あまえびたん」へメンションを飛ばすと、リプライを返してくれるだけのBotです。

途中、DB管理が必要な処理があったので、同僚の@rin_muさんにおしえて貰ったmongoHQを使ってみました。

今回書く内容程度のBotであれば、Rubyがある程度書けたら多分1時間くらいあれば作れると思います。
あと、mongoHQのまとまった日本語の記事はあんまり見つからなかったので一応登録からRubyでinsertしたりするまでを書いてみようと思います。


一応作ったモノはgithubに公開しているので思う存分眺めて下さい。
soplana / amaebitann



Botアカウントを作成する

TwitterBot用のアカウントを作成。



アプリケーション登録する

さっき作ったBot用アカウントでここに登録して、アプリケーションの登録を済ませます。
適当に情報を入力して登録が完了したら、まず「Settings」というタブにある「Application Type」という項目を「Read only」から「Read, Write and Access direct messages」とかに変更します。

f:id:soplana:20120329203234p:plain

次に、「OAuth Tool」というタブにある、Consumer key、Consumer secret、Access token、Access token secretをメモしておきます。

f:id:soplana:20120329203700p:plain

あまえびたんのアカウント情報が漏れまくってますがおかまいなしで続けます。



アプリにTwitterアカウントから許可を出しておく

これはやり方他にあるのかもしれませんが、僕はirbからauthorize_urlを取得して許可しました。
ってことでirbを起動します。

irb(main):001:0> require "oauth"
irb(main):001:0> c_key = "xxxxx"
irb(main):001:0> c_secret = "xxxxx"
irb(main):001:0> consumer = OAuth::Consumer.new(c_key, c_secret, :site => "https://api.twitter.com")
irb(main):001:0> r_token = consumer.get_request_token
irb(main):001:0> r_token.authorize_url
 # => "https://twitter.com/oauth/authorize?oauth_token=xxxxx"

これで取得できるURLをブラウザで開き、アプリを許可します。
次にブラウザに7桁のpinコードが表示されると思うのでその入力を行います。

irb(main):001:0> access_token = r_token.get_access_token(:oauth_verifier => 'メモったPINコード')
irb(main):001:0> access_token.token
 => "xxxx...."
irb(main):001:0> access_token.secret 
 => "xxxx...."

ここまでで下準備は大体完了でしょうか。



Botプログラムを書く

まずBot用のディレクトリを作ります。

$ mkdir amaebitann

こういう単発モノで入れるgemはそれぞれで管理したいのでGemfileを作ってbundleで必要なgemを入れます。
mongoDBとか使わないよ!!って方はtwitterだけ入れておけばいいと思います。

$ vim Gemfile

# Gemfileの中身
source 'http://rubygems.org'
gem 'twitter'
gem 'mongo'
gem 'bson_ext'
gem 'json'

$ bundle install --path bundle

これでamaebitannディレクトリ以下にbundleというディレクトリが出来てgemがそこに入ります。
gemを使用するrbファイルの先頭で、require 'bundler/setup'をすることでbundle以下のgemを見てくれるようになるそうです。
ここまで来たらいよいよBotプログラムが書けます。
amaebitann.rbを作成ます。適当にツイートしてみます。
consumer_key、consumer_secret、oauth_token、oauth_token_secretには最初のほうでメモった値を入れて下さい。

# -*- encoding: UTF-8 -*-
require 'bundler/setup'
require 'twitter'

Twitter.configure do |config|
  config.consumer_key       = 'xxxxx'
  config.consumer_secret    = 'xxxxx'
  config.oauth_token        = 'xxxxx'
  config.oauth_token_secret = 'xxxxx'
end

Twitter.update("test")

これで作ったBot用アカウントが「test」とツイートしてると思います!簡単!!
あとはタイムライン拾ってきたり、メンション拾ってきたりとかやりたい放題なので、

Ruby Twitter Gem簡易リファレンス
The Twitter Ruby Gem

この辺見ながらやれば大体やりたい事は出来るかと思います。




で、とりあえず「あまえびたん」に話を戻すと、あまえびたんは「メンションに反応してリプライを返すBot」なので、それっぽい動作をさせるためにはTwitter.mentionsで取得できるmention一覧に対してeachとかで処理すればいいのですが、これだと過去にリプライを返したツイートにも反応してしまいます。
なので一度反応したツイートはスルーするという処理が必要で、その為にDBにツイートIDを保存しておきたかったのです。
そこでmongoHQを使ってmongoDBにツイートIDを保存する仕組を作りました。
もっと良いやり方があるなら教えてください…。



mongoHQに登録する

mongoHQは名前の通りユーザ登録しておけば、mongoDBを使えるよになるクラウドサービスです。多分。
Freeプランだと16MBしか容量はありませんが、手軽さが魅力的なので、今回のようなケースにはもってこいです。
まずはここから新規登録します。
会員登録が終わると、会員画面にある「My Databases」ページにある「Add a Database」をクリックしてDBを追加します。
色々プランはありますが、Freeだと16MBのDBしか選べません。ザンネン。
僕はDB名は「amaebitann」で作成します。

f:id:soplana:20120329213952p:plain


f:id:soplana:20120329214144p:plain


f:id:soplana:20120329214516p:plain


DBの作成が出来たら、今度はそのDBにユーザを追加します。
「Database Users」タブからAdd a userをクリックしてユーザを追加します。
この際Read Only?にチェックを入れると、mongoDBへのinsertが出来なくなります。
僕は間違ってここにチェックを入れて作成してしまい、しばらくハマりました。

f:id:soplana:20120329233840p:plain


次に、「Database Info」タブを開きMongo URI をメモっときます。
後々Rubyから接続する時に必要になるからです。

f:id:soplana:20120329234224p:plain



まぁ…、amaebitannの漏れてはいけない情報が漏れまくってますがきにしません。


そしたらこれでDBが出来上がるので次はcollectionを作成します。
collectonはRDBで言うところの、tableみたいなものです。
先程作成したamaebitannをクリックして、「Add a Collection」をクリックし、適当な名前でcollectionを作成します。

f:id:soplana:20120329214918p:plain

f:id:soplana:20120329215114p:plain

これでDBとcollectionの準備が整いました。



RubyからmongoHQに接続する

はい。やっとここまで来ました。
どうやらRubyからmongoHQをいじるに当たってmongohq-rubyという便利なgemがあるようですが、今回は簡単な処理にとどまるので使用しません。
使うgemはmongo、urijsonの三つです。
では接続からデータのinsertとfindまでをやってみます。

# -*- coding: utf-8 -*-
require 'bundler/setup'
require 'mongo'
require 'uri'
require 'json'

# Database Infoでメモったmongo uriに、DB作成時に作ったuser:passwordを付けて
MONGOHQ_URL="mongodb://user:password@staff.mongohq.com:10037/amaebitann"

# ほとんど公式のサンプルのまま
def get_connection
  return @db if @db
  db      = URI.parse(MONGOHQ_URL)
  db_name = db.path.gsub(/^\//, '')
  @db     = Mongo::Connection.new(db.host, db.port).db(db_name)
  @db.authenticate(db.user, db.password) unless (db.user.nil? || db.user.nil?)
  return @db
end

# collection_nameの所に自分で作ったcollection名をいれてcollectionを取得
collection = get_connection.collection("collection_name")

# データをinsertしてみる
collection.insert(tweet_id: 1)

#データを取得してみる
collection.find(tweet_id: 1).first


RDBと違ってカラムの定義とかしなくていいからもうこれだけで動きます。
簡単なアプリならこれで、後はゴリゴリ書いていけるはずです。


で、後はcronで定期的に実行させて取り敢えずは完了です。


あまえびたんはgithubで公開していますので、自由に眺めたりして下さい。

soplana / amaebitann

「Leeno」をリリースするまでの話

「Leeno」というラクガキでコミュニケーションとって遊ぶアプリをリリースしました。

f:id:soplana:20120304173120p:plain



開発着手からリリースまでの話を纏めておきたいと思います。


■ サイトオープン自体は結構前

Leenoは今の形でリリースする前、2011年の5月くらいからサイト自体は存在しました。
しかし、何分僕自身にスキルが不足しまくっていた為、やりたい事であったり、デザインであったり、ソースコード自体の美しさであったり、色々不満が残る形でのリリースになっていました。
とは言え、当時僕自身のスキルレベルで言うと、それが限界でもあったので、運用という経験も積みたかったし一般公開に踏み切りました。
その後6月か7月あたりに、就職してしまったのでしばらくLeenoの面倒が見れなくてもどかしい日々を送っていました。



■ リニューアルの動機

それからまたしばらくして、秋〜冬くらいに仕事にも慣れてきたので余裕が出てきた頃、初期Leenoで不満があった部分に対して、自力で実装できるくらいのスキルが自分についたなーと。
同時に、Leenoを自分達で使ってみて色々思うところがありました。
使いづらい部分であったり、こういう機能があったらもっと楽しいのにな、という思いであったり。
実際使ってくれる人とかも結構いたりして、そういった方々からのフィードバックであったり、と。
なので、思い切って全部つくり直す事にしました。
0から! 全部!
なぜ、全部作り直したかというと、以前のソースが酷かったからです。ホントに。すみません。
アプリケーションの全体像がしっかり見えてからの開発というものは楽で、今回は色々スムーズにコーディングできて良かった。Railsにも慣れてきたし。



■ リリースまでの流れ

多分、開発に着手したのが10~11月くらいだったと思う。
HTML作成からRailsで書き終わったのが1~2月くらい。
僕は最初にHTMLモックを必ず作ります。ガッツりリソース割きます。
デザインがほぼ固まったら、Railsに乗っけて、それっぽく動作するよう表側を作ります。
デザインのっけた表側だけを作るだけなら、数日あればすぐ出来る話で、そこまで出来たら仲間に見せたり相談したりしてフィードバックを早い段階で貰います。
アプリケーションに対する哲学は徹底して共有した上で、とことん話しあったりするのも、大体このくらいの時期だと思います。
そこでガッツリ画面構成を変更したりします。
結果、一人で作ったモックやプロトタイプよりは格段にいい物になります。

その後アプリケーションがほぼ完成したくらいの時期に、周りの友人知人に声を書けて、テスト用サーバで可動させてる新Leenoを使い倒してもらいます。
協力してくれた方々、本当にありがとうございます。
この、知り合いに使い倒してもらうってのが本当に色々勉強になりました。
自分では「分かりやすい」とか「クール」とか思って作ってる機能やレイアウトですが、実際使ってもらうと全然思い通りにいきません。
とにかく不満や要望が出てくるので心が挫けそうになります。
直さないといけない、というのは理解出来るのですが、自分の中で色々考えぬいて作ってる機能だったりレイアウトだったりするだけあって、そこをつくり直すという決断を立て続けにしていくのは、本当に辛い作業でした。
とは言え、実際言われたように直してみると使いやすかったりするんですけどね。
まぁいただける意見の全てが正しい訳ではないのですが。時には断固として断るくらい哲学を持って作った方がいいかな、とは思います。

そうして使ってもらっては直して、という期間が大体一ヶ月くらい。
この作業によって、Leenoが現実に一般公開して、使ってもらった時のイメージを持てるクオリティになります。

その後、また一人でひたすらLeenoについて考えました。
その時、ふと思いついてスマホ用レイアウトを作ったりしました。
そうこうしてるウチに、そろそろリリースしていいのかもね、みたいな気持ちがふつふつと湧いてくるので(それが昨日)、ガガッ!!っとLeeno制作チームで集まってリリース作業しました。



■ 一緒にLeenoを作ってくれた人たち

まずはインフラ周りを担当してくれた、@happsくん。
忙しい仕事の合間に色々手伝ってくれたり、osやネットワークの事を丁寧に教えてくれるイカした人です。
旧Leenoの開発着手する前から色々相談乗ってくれたりしていたので本当に色々助けてもらいました。
サーバ監視、バックアップ、ログローテーション、サーバ構成などなど、実際手を動かして全部担当してくれました。


次に、@TomiTomi_Clubくん。
彼とは一番Leenoの事について話し合ったと思う。あまりに話しすぎて「おいィ」みたいな気持ちになることもありましたが、実際彼が言った通りに修正してLeenoは数倍良くなっています。
あと、家がたまり場として非常に優秀なので作業が捗ります。


最後に、新Leenoの開発から参戦してくれた@T_Hashくん。
Rails書けて、インフラ周りも出来るので、非常に助かる場面が沢山ありました。Gitの構築なんかもやってくれたし、うどんも詳しいし。
休日朝方までコーディングするといった荒行にも付き合ってくれるストイックな方なので、僕としてもモチベーションの維持にも繋がる関係でそういった面でも助かったかな、と。


彼ら以外にも、Leenoのロゴやアイコンを作っていただいたデザイナーさんや、テストに協力してくれた方達など、本当に恵まれた環境で開発できたなと思っています。
みなさん、忙しい合間をぬって沢山コミットしてくれたので感謝しています。ありがとうございます。



■ Leenoのこれから

昨今、話題になったりするアプリケーションは、社会的であったり個人的であったり、何かしら解決したい問題があってそれに対する解決をどうやってwebやアプリでしていくか、みたいなのが多いと思います。
Leenoはそれらとは全く逆で、暇つぶし系サービスかな、と。
別にアプリに大層な理由も解決したい問題もありません。ただ、使っていて楽しければそれでいいと思っています。
あと、おもいっきり馬鹿出来る場もweb上にあんまり無くなって来たかなとも思っていて、僕自身、結構息苦しいなと思っていたりします。
下品な言葉や、鋭いやりとり、そういうのがもうちょっとあってもいいのでは、と。
だからといって、別にLeenoで下品なやりとりしようぜ!!って言ってるわけではなくて、Leenoはガチガチなソーシャル指向であったり、リアルへのフィードバックを意識したサービスではないので、思う存分気軽に遊んでくれたらいいな、と考えている訳です。
今後もそこは絶対ブレずに開発していきます。


技術的にも面白いものはどんどん取り入れていきたいなと考えています。
もっともっと便利に使いやすく。

ただ、現時点では僕のスキルだとLeeno以上の物はつくれません。
これが僕の現時点のスキルです。
これからもどんどん勉強していって、もっともっと面白く馬鹿でいられるサービスにしていければいいなと思っております。

さくらVPSに、Rails3.1.1、MongoDB、Git、RVMなどを構築するときの手順

webサービスをリリースするにあたって、どうしてもテストサーバが欲しかったので、さくらの一番安いプランでVPSを借りました。
僕は非常に忘れっぽいので、Railsを起動して動作確認出来るまでのメモを残しておきます。
間違ってることもあるかもしれません。
環境は以下の通り。

  • Fedora14
  • Rails 3.1.1
  • MongoDB


Fedoraのインストール

以下の通りにやればおk。
http://support.sakura.ad.jp/manual/vps/mainte/custom_fedora.html



GroupとUserの追加
Fedoraインストール時に作成したrootユーザでsshログイン。
まずはグループの作成。

# groupadd -g xxx admin

xxxの部分は適当に。adminの部分に好きな名前をどうぞ。


次にユーザの作成。
xxxはさっき作成したグループのIDで。devの部分はお好きな名前でどうぞ。

# useradd -u yyy -g xxx -d /home/dev -m dev

yyyの部分は、

# cat /etc/passwd

で重複の無いIDを確認して指定すると良いです。


次に作成したユーザのパスワード作成

# passwd dev


次にsudoの度にpasswordを求められるのがダルいのでその設定

# visudo

開いたファイルの最終行に
%admin ALL=(ALL) NOPASSWD: ALL
を追加


これでdevユーザが作成されたので、一度ログアウトして、再度sshで接続確認するといいかも。
これ以降は上記で作ったユーザで作業します。



Gitのインストール
僕の場合は、今回のVPSはテストサーバに使いたかったので、Gitも入れます。
色々必要になりそうな物をついでに入れておきます。

$ yum install wget
$ yum install gccyum install make
$ yum install zlib
$ yum install zlib-devel
$ yum install perl-ExtUtils-MakeMaker
$ yum install tcl
$ yum install git

簡単ですね。



MongoDBのインストール
今回のプロジェクトはMongoDBを使っているので入れます。
MySQLと比べてなんと楽なインストールでしょうか。。

$ sudo yum -y install mongodb mongodb-devel mongodb-server

もう起動します。素晴らしい。

$ sudo /etc/init.d/mongod start



RVMのインストール
Rubyはrvmで管理します。

$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ source ~/.bashrc

1.9.2を入れるのですが、普通にいれてRailsを動かそうとすると、「linecache19」というgem関連で怒られます。多分。。
まぁ僕の環境ではopensslがどーのと言われて怒られました。なのでinstallする時に指定してあげましょう。
ついでにbundleくらいはinstallしましょう。

$ rvm install 1.9.2 --with-openssl-dir=$HOME/.rvm/usr
$ rvm 1.9.2
$ gem install bundle



ssh公開鍵の作成
僕は別のVPSにgitosisを構築して運用しているので、テストサーバでもリポジトリからcloneしてくるために、ssh公開鍵を作成しておきます。

$ ssh-keygen -t rsa


次にリポジトリからcloneする為に.ssh/configを作成しておきます。

$ vi ~/.ssh/config

ファイルの内容は以下の感じで。
xxxな部分は各々の環境に合わせて記述してください。
Host部分には好きな名前を設定してください。

$ cat ~/.ssh/config
Host hoge.vps
  Port xxxx
  HostName xxx.xxx.xxx.xxx
  IdentityFile ~/.ssh/id_rsa.pub

あとは、scpとかでこのユーザの~/.ssh/id_rsa.pubをローカルに持ってきて、gitosis.confにユーザ名を追加して
keydir/以下に、~/.ssh/id_rsa.pubの名前をユーザ名.pubに変更して置いて、pushすればおk。
で、再度、VPSに接続すればcloneできるハズ。

$ git clone git@hoge.vps:project_name.git



bundle install
無事、プロジェクトをclone出来たら、bundle install。

$ bundle install --path vendor/bundle

なにやら途中であれこれエラーが出るのでまとめて対処

$ sudo yum -y install flex libxml2-devel
$ sudo yum -y install libxslt-devel
$ sudo yum -y install gcc-c++



3000番ポートを解放する
iptablesこわい。バックアップとって作業。

$ sudo cp /etc/sysconfig/iptables /etc/sysconfig/iptables.org
$ sudo vi /etc/sysconfig/iptables




以上の設定が全部終われば、無事、 http://xxx.xxx.xxx.xxx:3000/ にアクセス出来ると思います。
ああ疲れた。




======追記======


rails consoleを使う

$ sudo yum install readline-devel
$ cd ~/.rvm/src/ruby-1.9.2-p290/ext/readline/
$ ruby extconf.rb
$ make
$ make install