SHOYAN BLOG

I am a pragmatic programmer.

Capistrano3-unicornを使う

capistrano3-unicornとは、capistranoでデプロイしたときにunicornのstart/restartをしてくれるgemです。
https://github.com/tablexi/capistrano3-unicorn

Install

Gemfileに以下を追記してbundle installします。

1
2
3
group :development do
  gem 'capistrano3-unicorn'
end

Capfileに以下を追記します。

1
require 'capistrano3/unicorn'

config/deploy.rbに以下を追記します。

1
2
3
4
5
6
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end

これで設定完了です。
cap deployすればunicorn restartが実行されるようになります。

注意点ポイント

設定していて少しわかり辛かった点があります。

unicorn.rbがデフォルトではCURRENT_PATH/config/unicorn/RAILS_ENV.rbに設定されています。
sinatraなどのrails以外のアプリケーションの場合は、RAILS_ENVがセットされていないため、CURRENT_PATH/config/unicorn/.rbのようになってしまいます。
ですので、明示的に設定が必要です。
しかし、設定方法についてドキュメントに明記されてないので少し戸惑いました。

設定はソースを参考にしました。

https://github.com/tablexi/capistrano3-unicorn/blob/master/lib/capistrano3/tasks/unicorn.rake#L4

unicorn_config_pathの設定

以下のようにlambdaを使って設定します。
config/unicorn.rbをunicorn_config_pathとして設定しています。
config/deploy.rb

1
set :unicorn_config_path, -> { File.join(current_path, "config", "unicorn.rb") }

cookbook_fileリソースでCookbookNotFoundが発生した

cookbook_fileでCookbookNotFoundというエラーがでた。
しかし、どこをどうみても合っているようにしか見えず、2時間ほどハマった。

エラーは以下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  * cookbook_file[/etc/nginx/nginx.conf] action create

    ================================================================================
    Error executing action `create` on resource 'cookbook_file[/etc/nginx/nginx.conf]'
    ================================================================================

    Chef::Exceptions::CookbookNotFound
    ----------------------------------
    Cookbook cookbooks not found. If you're loading cookbooks from another cookbook, make sure you configure the dependency in your metadata

    Resource Declaration:
    ---------------------
    # In /var/chef/cache/cookbooks/cookbooks/recipes/default.rb

     25: cookbook_file '/etc/nginx/nginx.conf' do
     26:   source 'nginx.conf'
     27:   owner 'root'
     28:   group 'root'
     29:   mode '0755'
     30: end
     31:

原因はmetadata.rbの名前。
cookbooks/site という構成でcookbookを作成しているのだが、cookbooks/site/metadata.rbのnameが’cookbooks’となっていた。
これによりcookbook_fileリソースがcookbooksというcookbookを参照していたが、そんなものはないのでCookbookNotFoundエラーが発生していた。
nameを’site’と変更してやることでうまくいくようになった。

Dockerでsystemctlでserviceが起動できない

centos7からsystemctlでserviceを起動するようになったが、Dockerで起動すると「Failed to get D-Bus connection: No connection to service manager.」というエラーメッセージがでて起動できないという問題が起こった。

1
2
3
$ docker run -it centos:centos7 /bin/bash
# systemctl
Failed to get D-Bus connection: No connection to service manager.

サービスを起動するためには以下の方法でコンテナを起動すればよい。

1
$ docker run --privileged -d --name httpd centos:centos7 /sbin/init

起動したコンテナでhttpdをinstallして起動する。

1
2
3
4
$ docker exec -it httpd /bin/bash
# yum install httpd -y
# systemctl enable httpd.service
# systemctl start httpd.service

プロセスを確認。起動できている。

1
2
3
4
5
6
7
8
9
ps aux | grep apache

bash-4.2# ps aux | grep apache
apache     168  0.0  0.3 221912  4028 ?        S    05:41   0:00 /usr/sbin/httpd -DFOREGROUND
apache     169  0.0  0.3 221912  4028 ?        S    05:41   0:00 /usr/sbin/httpd -DFOREGROUND
apache     170  0.0  0.3 221912  4028 ?        S    05:41   0:00 /usr/sbin/httpd -DFOREGROUND
apache     171  0.0  0.3 221912  4028 ?        S    05:41   0:00 /usr/sbin/httpd -DFOREGROUND
apache     172  0.0  0.3 221912  4028 ?        S    05:41   0:00 /usr/sbin/httpd -DFOREGROUND
root       180  0.0  0.0   9044   808 ?        S+   05:49   0:00 grep apache

yunanoさんの記事が大変参考になった。
http://qiita.com/yunano/items/9637ee21a71eba197345

Dockerでno Space Left on Deviceが出てbuildできなくなった

Dockerのbuild時に以下のエラーが発生するようになった。

1
2
3
$  docker build -t docker-and-chef .
Sending build context to Docker daemon 131.6 kB
Error response from daemon: mkdir /mnt/sda1/var/lib/docker/tmp/docker-builder670782655: no space left on device

PCを再起動してみても直らず、どうしたものかとググっていたら以下の情報を見つけた。
http://stackoverflow.com/questions/30604846/docker-error-no-space-left-on-device

やることは以下

  • docker ps -aして表示されたコンテナを消す。
  • docker images して表示されたイメージを消す。

コンテナはdocker rm container_idで消すことができる。
イメージはdocker rim image_idで消すことができる。

VMのディスク容量がないときに発生するエラーのようだ。
不要なコンテナがたくさんあったので、それらのコンテナを消すとエラーはでなくなった。

PHPコーディング規約とサポートするツール

この記事の内容

PHPのコーディング規約とそれをサポートするツールの紹介です。
座学形式で説明していきます。

概要を知りたい場合は以下のスライドを参照ください。

はじまり、はじまり

みなさん、こんにちは。
PHPが大好きなプログラマことshoyanです。

今回、PHPのコーディング規約とそれをサポートするツールの紹介をしたいと思います。

なぜ必要か

まずはなぜコーディング規約が必要なのでしょうか?

みんなに質問してみる
しばらく沈黙

目のあった人に質問する
なんか適当に答えてくれる

ありがとうございます。
正解です。
補足として、なぜコーディング規約が必要になったかを説明します。

そもそもコーディング規約は一人で開発する場合には必要ありません。
二人以上で開発を行う場合に必要となってきます。

たとえば、太郎くんとドナルドさんが二人で開発をしていたとします。
太郎くんがコードレビューを依頼しました。
30分後に確認するとコメントがついていました。

1行で書いていたif文のコードにドナルドさんからコメントがついていました。
少し下にスクロールすると、if文のあとにスペースが必要だとコメントが入っていました。
少し下にスクロールすると、else ifのスペースは不要だとコメントが。
また更にその下には改行は不要とのコメントが…
なんと全部で30個のコメントがついていたのです。
30個のコメントの27個はコーディングスタイルに関するコメントでした。

さて、このレビューは有益でしょうか。
お互いにとってあまり有益ではありませんね。

じゃあ、どうしましょう。

そこでコーディング規約です。
コーディング規約という共通のルールを作ることにより、お互いが納得できるコードを書く指標をつくります。

さて、コーディング規約に則ったコードを書くぞ!となったとしましょう。
では、PHPのコーディング規約を探してみましょう。
ところが、PHPの本家にはコーディング規約のドキュメントがありません。

ということは、共通ルールがないということになります。
PHPの本家はコーディングルールなんて知ったこっちゃない。
開発者が勝手にやってくれ。ということです。

その要望に答えてPHPにはコーディング規約が乱立しています。
たとえば、以下のような感じです。

このようにフレームワークごとにコーディングルールが定められています。

1つのフレームワークであれば問題はありません。
しかし、2つのプロジェクトがあって、別々のフレームワークを使っていたらどうでしょう。
開発者はそれぞれのフレームワークの規約を切り替えながら開発をしないといけません。
これは考えるだけでも面倒くさそうですね。

PSR

このような現状をなんとかしようと策定されたのがPSRです。
PSRはPHP Standards Recommendations の頭文字をとったものです。
日本語にするとPHP標準勧告です。
PHP Framework Interop Groupが策定しています。

PSRのゴール

We’re a group of established PHP projects whose goal is to talk about commonalities between our projects and find ways we can work better together.

要するにフレームワークに依存しないルールを作って、どのプロジェクト(どのフレームワークを使っているプロジェクト)でも
同じようにコードを書くことをできるようにしましょうということです。(意訳)

ちなみにPSRには状態が色々あって、正式なものはACCEPTEDです。
ほかにも、DEPRECATED、REVIEW、DRAFTがあります。
以下のページで見ることができます。
http://www.php-fig.org/psr/

StatusがACCEPTEDなPSRは1〜7があります。
その中のPSR1とPSR2をここでは紹介します。
PSR1はBasic Coding Standardが定義してあります。
PSR2はCoding Style Guideで、PSR1を拡張したものです。
詳細は以下のページをご覧ください。

PHP Code Snifferについて

PHPのコーディング規約をチェックするツールはいくつかありますが、ここではPHP_CodeSnifferを紹介します。

Snifferは嗅覚性探知機という意味です。

たとえば、捜索犬はsniffer dog 、ガス探知機はgas snifferと英語でいいます。
要するにPHP Code探索機です。

PHP Code Snifferにはツールが2つあります。
1つめはphpcsです。

phpcsはコーディングスタイルのチェックをするツールで、PHP Code Snifferを略したものです。
コーディングスタイルを指定することができます。
指定できるコーディングスタイルは、MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend です。
また、コーディングルールを自分で設定することもできます。

実行コマンド

1
phpcs --standard=PSR2 check_file or check_dir/

2つめはphpcbfです。

PHP Code Beautifier and Fixerを略したツールです。
これは自動でコードを修正してくれるツールです。

実行コマンド

1
phpcbf --standard=PSR2 check_file or check_dir/

PHP Code Snifferのいいところは、チェックと修正のツールがわかれているところです。
それにより、CIによるチェックとその修正が簡単に行えます。

PHP Code Snifferの詳しい使い方はWikiを参照ください。
https://github.com/squizlabs/PHP_CodeSniffer/wiki’

コーディング規約の運用

コーディング規約を運用していくにあたっての問題点はなんだと思いますか?

しばらく沈黙

「コーディング規約が存在してもあまり守られない」ことです。

多分、みんな納得

では、どうすればコーディング規約を守れるようになるでしょうか。

CIでチェックするのが1番です。

コーディング規約に違反しているコードがあればエラーにします。
そうすればコーディング規約を違反しているコードがmasterにマージされることはありません。

コーディング規約の導入はプロジェクトの初期から始めるのがベストですが、
途中からでも自動修正ツールを使えば大半は修正することができます。
また、CIのプラットホームが最近は充実しているのでチェックの自動化も容易に行えます。

実際に導入した記事を書きましたので、こちらも参考にしてください。