読者です 読者をやめる 読者になる 読者になる

肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

全てのサイトをぼかす UserStyle つくりました

fluentd casual talks で一番感動したのはやっぱこれだとおもうんですよ

デモのぼかしについて

ぼかしたいところに、ブラウザのユーザCSSで以下のルールを適用しています。

.bokasitai {
   color: transparent;
   text-shadow: 0 0 10px #333;
 }
[fluentd] #Fluentd Casual Talks で「fluentdでWebサイト運用を楽にする」話をしてきました - 酒日記 はてな支店

で、さくっとつかいたかったんで、UserStyle.org に登録しておいたってだけのはなしです。

デモの前に有効化すればいいだけ!便利!

phpenv + php-build を使って 5.3 と 5.4 を共存させつつ php-fpm を使う

っていう話なんですが、前提として、 phpenv + php-build は他にも多くの方が語ってるので、そちらを参考に。いやむしろ僕も参考にさせていただきました、ありがとうございます、いくら安いとはいえこれで PHP 5.4 のためにVPS1台借りるとかってことがなくなってよかったです。というか @yuya_takeyama さんのおかげですありがとうございます。


なんですが、えーっと、作るのはだいたいWebアプリで、cli の php が複数バージョンいれられるのは大変嬉しいけどそれだけだと PHP 5.4 なら built-in server があるからいいけど PHP 5.3 の開発とか困るねってことで、php-fpm も入れたいと思います。


流れ

  • enable-fpm で php-build する
  • そんな fpm プロセスを立ち上げる
  • nginx とか設定する

enable-fpm で php-build する

まず、php-build むけのカスタムな設定をつくります。5.4.0s でつくります。s-suffix は sotarok の s です。

$ v ~/.php-build/share/php-build/definitions/5.4.0s

内容はこんなかんじ。全部入りです。configure_option をいじるんですけど、 --enable-fpm だけあればいいんですけど、 --with-mysql-sock=/tmp/mysql.sock とかいれてるのは好みの問題なので、いれなくても良いはずです。

configure_option "--enable-fpm --enable-fileinfo --enable-hash --enable-json --enable-sysvsem --enable-sysvshm --enable-sysvmsg --enable-bcmath --with-bz2 --enable-ctype --with-iconv --enable-ftp --with-gettext --enable-mbstring --with-onig=/usr --with-pcre-regex --with-mysql=mysqlnd --with-mysql-sock=/tmp/mysql.sock --enable-phar --enable-shmop --enable-sockets --enable-simplexml --enable-dom --with-libxml-dir=/usr --enable-tokenizer --with-zlib --with-kerberos=/usr --with-openssl=/usr --enable-soap --enable-zip --with-mhash=yes --without-mm --with-enchant=/usr --with-zlib-dir=/usr --with-gd --enable-gd-native-ttf --with-gmp=/usr --with-jpeg-dir=/usr --with-xpm-dir=/usr/X11R6 --with-png-dir=/usr --with-freetype-dir=/usr --with-imap=/usr --with-imap-ssl --enable-intl --with-t1lib=/usr --with-mcrypt=/usr --with-snmp=/usr"
install_package "http://www.php.net/distributions/php-5.4.0.tar.bz2"
install_pyrus
install_xdebug_master

で、これを指定してインストール

$ php-build 5.4.0s ~/.phpenv/versions/5.4.0s


ところで、そういえば、php-build が install_pyrus でコケる現象が前あって、デバッグってことで install_pyrus まわりにログを仕込んでると動いたりしてなんか原因が特定できなかったです。
ちなみに、install_pyrus って php ビルドした後に実行されるんでが、これにコケると、php 本体の make は成功してるのにこれまるごと cleanup されちゃうっていう仕様になってて悲しい思いをしたので、 cleanup 処理はコメントアウトしちゃってます。

~/.php-build/bin/php-build

428 # Handles build errors, and displays the last 10 lines
429 # of the build log.
430 function build_error {
431     {
432         echo
433         echo "BUILD ERROR"
434         echo $(tail -n10 "$LOG_PATH")
435         echo
436         echo "The full Log is available here ${LOG_PATH}"
437         echo
438     } >&3
439
440     # Removes the prefix when the build fails.
441     #cleanup_abort # ←ここをコメントアウトしてる
442 }

PHP-FPM の設定

話がそれました。
で、php-fpm つきでビルドができると、以下のように sbin/php-fpm が生成されます。

$ ls -la .phpenv/versions/5.4.0s/sbin/php-fpm
-rwxr-xr-x 1 sotarok sotarok 31055874 2012-05-02 00:38 .phpenv/versions/5.4.0s/sbin/php-fpm

こいつをおもむろに実行してみると、

$ cd .phpenv/versions/5.4.0s
$ ./sbin/php-fpm
[22-May-2012 16:16:27] ERROR: failed to open configuration file '/home/sotarok/.phpenv/versions/5.4.0s/etc/php-fpm.conf': No such file or directory (2)
[22-May-2012 16:16:27] ERROR: failed to load configuration file '/home/sotarok/.phpenv/versions/5.4.0s/etc/php-fpm.conf'
[22-May-2012 16:16:27] ERROR: FPM initialization failed

php-fpm.conf つくらなきゃいけない感じがします。(php-build でなんかひっかけてつくればいいんですよね多分、面倒だから見てないけど、多分そう。)

ってことで、 ~/.phpenv/versions/5.4.0s/etc/php-fpm.conf に 適当にファイルを作成します。

  • https://gist.github.com/2767859
    • path とか適当に変えてください。
    • デバッグのために、 daemonize = no とかに設定してます。このほうが再起動とか楽なので。で、そうするとターミナルとられちゃうんですけど、どっちにしろ screen で1つわりあてちゃえばいいだけのはなしです
    • listen を 127.0.0.1:9002 とかにしてます

あとは... あ、あとそうだ、なんか適当な位置にログをおきます。もし ~/var/log とかなかったらつくってください

で、起動!

$ ~/.phpenv/versions/5.4.0s/sbin/php-fpm
[22-May-2012 18:44:48] WARNING: [pool www] 'user' directive is ignored when FPM is not running as root
[22-May-2012 18:44:48] WARNING: [pool www] 'group' directive is ignored when FPM is not running as root
[22-May-2012 18:44:48] NOTICE: fpm is running, pid 787
[22-May-2012 18:44:48] NOTICE: ready to handle connections

pool の user, group は root じゃないとうごかないよーって警告でるんですが、コメントアウトすると、起動しないです。root では動かさないので、まぁ、適当です。

で、これで fastcgi で受け付ける準備ができました。

nginx の設定とか

127.0.0.1:9002 で受け付ける upstream を定義します。

upstream php54 {
    server 127.0.0.1:9002;
}

# {{{ z.merlot.strk.jp;
server {
  listen 80;
  server_name z.merlot.strk.jp;
  index index.php;
  root /usr/local/var/www/z.merlot.strk.jp/public;

  location / {
    if (!-e $request_filename) {
      rewrite ^(.*)$ /index.php$1 last;
    }
  }

  location ~ \.php.*$ {
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_pass php54;
    fastcgi_index index.php;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
  }
}
# }}}

で、再起動。

z.merlot.strk.jp にアクセスすると、

あとは

5.3.13 とかも同じ方法でつくって、fpm は listen port かえて、nginx の設定で、こいつを指定すればいいですね。

upstream php53 {
    server 127.0.0.1:9003;
}
# {{{ p.merlot.strk.jp;
server {
  listen 80;
  server_name p.merlot.strk.jp;

  # .. (snip)

  location ~ \.php.*$ {
    # .. (snip)
    fastcgi_pass php53;
    # .. (snip)
  }
}
# }}}


これで快適に fpm 環境のテストもできるし、phpenv つかったものの、phpenv でバージョンを切り替える必要すらなく、port を指定して別の php-fpm プロセスをたちあげておけば、幸せに複数バージョンで開発をすすめられるし、ホスト別に分けるのはもう nginx の設定で適当にすればいいので、楽チンです。

enjoy it!

今更Perfumeに興味が出てきた人がとりあえず聞いておくべき5曲

あくまで俺の中で、なので、他の人の視点だともっと色々あるかもしれない。ま、それはそれぞれの人の視点ってことで!
好きな曲がありすぎて5曲とか選びづらいけど...

1. エレクトロ・ワールド


エレクトロ三部作(エレクトロ・ワールド、コンピューターシティ、リニアモーターガール)の中でもひときわ輝く神曲。

2. チョコレイト・ディスコ


俺の中では Perfume の代名詞。2008年、Perfumeをききはじめたときずっとヘビロテしてた。バレンタインデーといえば Perfume

3. ナチュラルに恋して


かわいい曲です。かわいい曲といえばこれか love the world かってところで相当悩みますが。

4. 願い


エレクトロ風のポップで元気の良い曲が多い Perfume だけどバラードも歌ったりしてて、この曲はしばらくライブのトリで歌ってたなあ。

5. SEVENTH HEAVEN


ポリリズムのカップリングで収録されてた神曲。ライブでもめったにやらないので、やったときの会場のどよめきは異常。PVはオリジナルでは多分存在しなくて、これは誰かが作ったやつだと思う。

おまけ

道捺大陸(元 道夏大陸)。その昔情熱大陸風の動画を作った神がいて、俺はこの動画で色々みてたらはまっちゃったので、とりあえず全部見てみると良いかもしれない。

1:

2:

3:


アイドルには、ストーリーが必要だとおもうんですよね、応援しちゃいたくなるみたいな、ね。

Capistrano の on_no_matching_servers で no servers matched でもタスクを継続する

Capistrano で role を指定してtaskつくったり、role を指定して run したときに、その対象の role がサーバリストにないと、

$ cap apache2:afterdeploy
  * 17:54:40 == Currently executing `apache2:afterdeploy'
  * executing "sudo -p 'sudo password: ' a2ensite crocos"
`apache2:afterdeploy' is only run for servers matching {:roles=>:apache2}, but no servers matched

などとなって、止まってしまう。

これはだるいなーとおもっていたところ、patch 的な gist を見つけ、議論を追っていたら pull request されとりこまれていたようだ。9 months ago だから結構前かな。とりあえず手元では 2.11.2 で確認。

で、

task に指定したり、

    desc "apache2 after deploy"
    task :afterdeploy, :roles => :apache2 do
        ...
    end

run に指定したりすれば、

    run "#{sudo} a2ensite crocos", :roles => :crocos_markting, :on_no_matching_servers => :continue

今度は実行される

$ cap apache2:afterdeploy
  * 17:54:30 == Currently executing `apache2:afterdeploy'
  * executing "sudo -p 'sudo password: ' a2ensite crocos"
 ** skipping `apache2:afterdeploy' because no servers matched
  * executing "sudo -p 'sudo password: ' ...
    ....
    command finished in 91ms

めでたしめでたし。

dh-make-pecl (dh-make-php) を使って5分でPECLパッケージをオレオレ.debにする

PEAR だったらデプロイするアプリ内に配置すれば良いのだけど、PECLとかこまりますよね。
あと、どうしても、サーバ複数セットアップとかしてたらいちいち pecl コマンド叩くわけにもいかないので、パッケージ管理をしておきたい感じになります。とはいっても、Debian にしても、CentOS にしても、OSのほうで提供してるaptやyumでのパッケージだと、ライブラリのバージョンアップに追いついてなかったりして困りますよね。

ってことで、社内とかで利用するときに .deb とかつくりたい!

でも Debian パッケージってどうやってつくればいいかわからない!

ってまぁ、そういうことなんですけど、Debianには安心の dh-make のヘルパーがいくつかあるので、それの使い方を紹介します。

  • (今回の環境は squeeze 6.0.4)

準備

Debianパッケージ化に必要なやつをインストールしておきます (gccとかは当然入ってるよねってことで書いてないけど、もし入ってない人は build-essentials なども必要ですよ)

$ sudo apt-get install devscripts dh-make dh-make-php

もし入ってなかったら php5-dev も必要です

$ sudo apt-get install php5-dev

パッケージャー名とかを登録しておきます。

export DEBEMAIL="sotarok@crocos.co.jp"
export DEBFULLNAME="Sotaro Karasawa"

あと、とりあえず作業用ディレクトリに移動しておきます。

$ mkdir ~/tmp/apc-deb
$ cd ~/tmp/apc-deb

パッケージ化したいソースを取得し、pecl パッケージをつくる

今回は、apc を例にやります。*1

pecl ですでに配布されているバージョンをパッケージングする場合は、

$ pecl download apc

で、apc-3.1.9.tgz などを取得します。


... が、今回は、SVN からパッケージングします。なぜなら APC が PHP 5.4 に対応してるのはまだ SVN 版だからです。

$ svn co https://svn.php.net/repository/pecl/apc/trunk ./apc-src
$ cd apc-src

このまま peck package したいところですが、開発版だと package.xml の version がアレなので、そこだけ編集します。

--- package.xml (リビジョン 324826)
+++ package.xml (作業コピー)
@@ -72,7 +72,7 @@
   </developer>
   <date>2012-03-15</date>
   <version>
-    <release>3.1.10-dev</release>
+    <release>3.1.9.99</release>
     <api>3.1.0</api>
   </version>
   <stability>

で、package

$ pecl package
...
Package APC-3.1.9.99.tgz done
Tag the released code with `pear svntag package.xml'
(or set the SVN tag APC-3.1.9.99 by hand)

これで、tgz ファイルができあがりました。

いよいよ dh-make-pecl

ちょっとファイルを移します。

$ cd ..
$ mkdir deb
$ mv apc-src/APC-3.1.9.99.tgz ./deb
$ cd deb

--only 5 をつけて dh-make-pecl します

$ dh-make-pecl --only 5 APC-3.1.9.99.tgz

すると、いくつかファイルが生成されます。

$ ls
APC-3.1.9.99.tgz  php-apc-3.1.9.99  php-apc_3.1.9.99.orig.tar.gz

この php-apc-3.1.9.99 ディレクトリが、apc のソースとdebianディレクトリを含む、debian パッケージのひな形になってます。このディレクトリに入り、おもむろに debuild。

$ cd php-apc-3.1.9.99
$ debuild -uc -us
...

dpkg-buildpackage: source changed by Sotaro Karasawa <sotarok@crocos.co.jp>
 dpkg-source --before-build php-apc-3.1.9.99
dpkg-buildpackage: host architecture amd64
dpkg-checkbuilddeps: Unmet build dependencies: xsltproc
dpkg-buildpackage: warning: Build dependencies/conflicts unsatisfied; aborting.
dpkg-buildpackage: warning: (Use -d flag to override.)
debuild: fatal error at line 1325:
dpkg-buildpackage -rfakeroot -D -us -uc failed

ビルド系の依存関係でビルドが失敗した場合は、apt-get でインストール。 "dpkg-checkbuilddeps: Unmet build dependencies:" に書いてあるやつが、足りてないやつです。このように、失敗したときは適当に apt-get でインストールします。

$ sudo apt-get install xsltproc

さて、再挑戦。

$ debuild -uc -us

...

dpkg-deb: `../php5-apc_3.1.9.99-1_amd64.deb' にパッケージ `php5-apc' を構築しています。
 dpkg-genchanges  >../php-apc_3.1.9.99-1_amd64.changes
dpkg-genchanges: including full source code in upload
 dpkg-source --after-build php-apc-3.1.9.99
dpkg-buildpackage: full upload (original source is included)
Now running lintian...
W: php-apc source: ancient-standards-version 3.8.1 (current is 3.9.1)
W: php5-apc: copyright-refers-to-versionless-license-file usr/share/common-licenses/GPL
W: php5-apc: new-package-should-close-itp-bugFinished running lintian.

で、一個上のディレクトリに移動すると

$ ls -la
合計 316
drwxr-xr-x 4 sotarok sotarok   4096 2012-04-05 13:19 .
drwxr-xr-x 4 sotarok sotarok   4096 2012-04-05 13:17 ..
drwxr-xr-x 6 sotarok sotarok   4096 2012-04-05 11:50 .svn
-rw-r--r-- 1 sotarok sotarok 156206 2012-04-05 13:17 APC-3.1.9.99.tgz
drwxr-xr-x 5 sotarok sotarok   4096 2012-04-05 13:19 php-apc-3.1.9.99
-rw-r--r-- 1 sotarok sotarok   5032 2012-04-05 13:19 php-apc_3.1.9.99-1.diff.gz
-rw-r--r-- 1 sotarok sotarok    755 2012-04-05 13:19 php-apc_3.1.9.99-1.dsc
-rw-r--r-- 1 sotarok sotarok  43787 2012-04-05 13:19 php-apc_3.1.9.99-1_amd64.build
-rw-r--r-- 1 sotarok sotarok   1481 2012-04-05 13:19 php-apc_3.1.9.99-1_amd64.changes
lrwxrwxrwx 1 sotarok sotarok     16 2012-04-05 13:19 php-apc_3.1.9.99.orig.tar.gz -> APC-3.1.9.99.tgz
-rw-r--r-- 1 sotarok sotarok  74678 2012-04-05 13:19 php5-apc_3.1.9.99-1_amd64.deb

php5-apc_3.1.9.99-1_amd64.deb ってファイルができてましたね!

インストールしてみる

$ sudo dpkg -i php5-apc_3.1.9.99-1_amd64.deb
未選択パッケージ php5-apc を選択しています。
(データベースを読み込んでいます ... 現在 55932 個のファイルとディレクトリがインストールされています。)
(php5-apc_3.1.9.99-1_amd64.deb から) php5-apc を展開しています...
php5-apc (3.1.9.99-1) を設定しています ...
$ php -m | grep apc
apc

ちなみに、phpinfo上で見るバージョンは、拡張機能のソースから取得されたものなので、3.1.9 とかになってます(debianパッケージのバージョン 3.1.9.99とは連動してないですよってこと)

簡単でしたね!

  • 準備さえできてれば、5分もかからないですね!
  • 必要なら apc.ini を書き換えたものを準備しておけば、一緒にパッケージングすると、インストールするだけで社内向けの apc.ini が入る、などといったパッケージを作れます。

*1:まぁ、ようするにこれがPHP 5.4 に対応してないから、独自でパッケージングしたい!というわけなんですけどね

PHP勉強会@東京 #58 で「入門PHP5.4」の話をしました

久しぶりのPHP勉強会でしたね!僕も通常のPHP勉強会での発表は久々だった気がします。
というわけで、入門PHP5.4という題で発表してきました。

発表資料&リンク集

Speaker Deck にあげました。

が、Speaker Deck だと、リンクがリンクにならないので、リンク集だけ補足でこちらにおいておきます!

Accessor の例

今日途中でコーディングしてたネタです。この Accessor Trait は、 id:Fivestar と僕が同時期にまったく同じ機能の Trait を作ってたりして、ワロタって話をしました。いや実際このあたりを作りたくなるものですね!

<?php

trait Accessor
{
    // そういやこれだと camelCase な property しか対応してないけど
    public function __call($name, $params)
    {
        if (strpos($name, 'get') === 0) {
            $attr = substr($name, 3);
            if (strlen($attr) > 0) {
                $attr = lcfirst($attr);
                if ($this->hasClassVar($attr)) {
                    return $this->$attr;
                }
                throw new \LogicException(sprintf('No such field "%s"', $attr));
            }
        }
        if (strpos($name, 'set') === 0) {
            if (count($params) !== 1) {
                throw new \InvalidArgumentException('error');
            }
            $attr = substr($name, 3);
            if (strlen($attr) > 0) {
                $attr = lcfirst($attr);
                $value = array_shift($params);
                if ($this->hasClassVar($attr)) {
                    $this->$attr = $value;
                    return $this;
                }
                throw new \LogicException(sprintf('No such field "%s"', $attr));
            }
        }

        throw new \LogicException(sprintf('Method not found "%s"', $name));
    }

    private function hasClassVar($attr)
    {
        static $vars = null;
        if ($vars === null) {
            $vars = get_class_vars(__CLASS__);
        }
        return array_key_exists($attr, $vars);
    }
}

で、これを use するだけで Accessor ができますねってはなし。

<?php

class User
{
    use Accessor;

    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }
}

$user = new User('aoi miyazaki');
var_dump($user->getName());         // => aoi miyazaki
$user->setName('aoi yu');
var_dump($user->getName());         // => aoi yu

まとめ

  • Voyage Group さんのセミナールーム広いし綺麗だし快適
  • Ajito いいなー

MyMR、Phake、懇親会も楽しかったです!最後に、会場を貸してくださった Voyage Group さん、幹事の gusagi さんありがとうございました。

Travis CI で、Organization のリポジトリの設定をする

GitHub と連携した CI 環境の Travis CI で、通常、自分の保持するリポジトリは OAuth でログインすると一覧に現れるのですが、Organization のリポジトリの設定は手動で設定しなければいけません。あと、そのリポジトリの admin 権限が必要です。

Admin の Service Hooks へ行く

  • Domain は空でもOK。入れるとしたら「travis-ci.org」
  • User は自分のユーザ名
  • Token は、travis-ci.org にログインすると、Profile ページに記載されている Token
  • Active にチェック


これだけです。手動なのは多少面倒だけど設定できてよかった。

e.g. http://travis-ci.org/#!/fluent/fluent-logger-php