トップ 最新 追記

2015-04-05 [長年日記]

_ dotenvで秘密情報を扱う件 〜 Ruby, PHP, PaaS, CI について 〜

.envファイルに環境変数を書いておく

dotenv って何かと一言で言うと Foreman の提供している .env ファイルから環境変数をセットする機能を Foreman 環境以外でも利用できるようにしたもの。

えーと。何のこと?って感じですね。

dotenv という言葉は意味する範囲がやや曖昧なんだけど、自分の場合は「.env ファイルに sh script のように環境変数を記述しておくと、アプリが実行時に自動的に環境変数として取り込むことができる系の機能の総称」と捉えている。

で、実装がそれぞれにある。いちばん有名な Ruby バージョンだと予想通り Dotenv gem で、他の言語でも似たようなものがいくつもある。

bkeepers/dotenv

なぜ.envファイルから環境変数をセットするのか

環境変数から設定を取得したり環境判別用の情報を取得しようという話は決して新しい話ではない。例えば Rails では以前から RailsEnv や RackEnv という環境変数を見て環境を切り替えるという機能があって、そのために Apache の httpd.conf に SetEnv とか書いたことのある人もいると思う。

つまり production では環境変数から情報を取得することができるというのは割とポピュラーな手法。しかし手元の開発環境ではこれらがセットされていないことが多く、設定用のコードで環境変数がセットされている場合とセットされていない場合を判別して処理する必要が出てきたりする。そうなると煩雑だしバグのもとになるし、環境変数をセットしつつ rails server を起動するのも面倒くさい。一度実行すれば履歴に残るだろうけど、そういう理解もコマンドライン環境への習熟度合いに大きく左右される。

そこでこの環境変数の扱いが抽象化されているといいよねとなって、.env ファイルから環境変数を自動でセットする方法が生まれた。書き方は sh script と同じ。rails server の起動のたびに環境変数をセットする必要もないし、楽ちん。

当初これを実現したのは Procfile を使って関連するプロセスを起動する Foreman だったようだ。しかしこの .env ファイルを扱う機能はプロセスの管理とは独立して便利なので Dotenv が生まれた。

cf. http://opensoul.org/2012/07/24/dotenv/

環境変数と秘密情報

なんでいま環境変数の話なのかというと、

秘密情報をどう扱うか?

が問題になるケースが増えてきたから。例えば AWS や Google はじめ各種 API を利用するのに key, secret, credential と呼ばれる秘密情報が必要になる。これら

秘密情報をアプリケーションコードの中、repositoryの中に直接置かずに利用したい。

直接 repository に入れてしまうと production と development で同じ秘密情報が利用されてしまったりするし、公開 repository で開発する場合や、private repository でも外部のパートナーと共有する場合はそもそも秘密情報を含むことはできない。

ということで環境変数経由でこういう情報は利用しましょうというのが最近の作法となっている。

cf. The Twelve-Factor App(日本語訳)

改めてdotenvと秘密情報

ということで、環境変数で秘密情報を渡すようにしてアプリや repository の中に入れないようにしましょう、そのために dotenv が使えるよということなんだけど、その時にこれを守っていないと台無しになってしまうのは、

.env は .gitignore しておくこと

これやらないとツールが増えるだけで、情報の扱いは変わらないので。

PaaS, CIと環境変数

自分で立てたサーバならアプリケーションの実行環境に環境変数をセットするのは自由にできるけど、昨今の Web 開発を支える便利サービス、PaaS や CI サービスはどうなっているのかと思い、ざっと調べてみた。

Heroku は Twelve Factor App という文書でアプリケーションを portable にするために環境依存の設定は環境変数を通じてセットしようと提唱しているように、Heroku はじめ各種 PaaS ではアプリケーションの実行環境に環境変数をセットする方法を提供している。とりあえず確認したところ Heroku, Mogok には Web UI から環境変数をセットする機能がある。

Sqale は 2015-04-05 時点では Web UI からの設定はできなくて、逆に .env ファイルを production で使うように奨めている。.env ファイルは基本的にプロジェクトルートに置くので、これは公開 repository では使えない方法である。そこで解決策として deploy ごとにクリーンになってしまわない領域に秘密情報を置いて、postinstall スクリプトで symlink を作るという方法を提供している。ただ ssh で作業する必要があり、Un*x 系サーバに不慣れな人にはちょっと向かない方法だ。また、この方法は ssh でアクセスできる人には秘密情報はバレてしまうということでもある。

Sqale - FAQ: 技術的な仕様に関する質問

EngineYard も Web UI はなくて Sqale のようにアプリケーション環境内の消えない領域にファイルを置く形のようだ。

Engine Yard CloudでPHPを利用する : Developer Center

CI については以前調べた時のついーとを貼付けておく。

あとこんなこと言ってる人がいた。

えーとまとめるとメジャーなCIサービスは環境変数を Web UI からセットできるようだ。Drone.io もできるってさ。

dotenv系ツール

最後はツールを紹介しておしまい。

Dotenv gem

この Dotenv gem は foreman のようにコマンドとしても使え、dotenv コマンド経由でアプリを起動すれば Ruby 以外の言語でも同じように .env から環境変数をセットできるようだ。

bkeepers/dotenv

使い方は、

1. require 'dotenv' して Dotenv.load(*args)

require 'dotenv-rails' してしまうと load は引数を受け取れないので注意。

2. dotenv bundle php -S localhost:3000

この場合は dotenv 経由で起動したプロセスに環境変数がセットされる。

direnv

Dotenv は ruby のコード内で .env からの読み込みを明記したり、dotenv コマンド経由でアプリケーションを起動する必要がある。

対して Direnv は rvm, rbenv が用意しているような、shell を hook して特定のディレクトリに入った時だけ特定の環境変数をセットすることができる Go 製のツール。

つまり、アプリケーションコード内で env のロードを明示する必要がなく、アプリケーションの言語に依存しない代わりに shell の設定が必要になる。

これは伝統的な PHP アプリ開発者には向いていないかも。あと、アプリケーションコード内に環境変数の設定に関する記述がなくなるので、そのノウハウの共有は十分注意して行う必要があるような気がする。

phpdotenv

vlucas/phpdotenv

.env が読み込めない時に例外が上がっちゃう。ちょっとちょっと。しかも超汎用的な InvalidArgumentError なのでハンドリングが難しい。なーーーんでそんなことするの。

php-dotenv

josegonzalez/php-dotenv

読み込みの記述が Dotenv gem に比べると冗長。

Laravel + Dotenv

Laravel は 4 の時点では自前で .env.php を扱っていたが、Laravel 5 では Dotenv を使うように変わっている。

うーん、簡単に Fatal Error になっちゃう方を採用したのね。なんか方法考えないとな。

あと、当然気づいてると思うけど npm にもある。 dotenv ま、イマドキだいたいどの環境でも使えるんだと思う。


2015-04-25 [長年日記]

_ 初めてPackagist.orgに登録してみた

あるいは久しぶりに書くけど Kanazawa.rb meetup 32 に参加してきた話。

今回は「意識高いもくもく会」。初参加の方が3名もいて、暖かくなってきたのもあって、新しい風を感じたりしていた。

今日の自分の課題は packagist への package 登録。

packagist.orgとは

まず Composer ってのがある。これについては以前まとめたのがあるので、もしまだよく分かっていないということであれば参照のこと。要は Ruby の Bundler のようなもの。

今さらComposer - あーありがち(2014-07-02)

で、デフォルトのリポジトリが packagist.org で、ここに自作のパッケージを登録しようと思ったのが始まり。

composer, packagist って利用方法の記事は多いけど、作る系の情報って全然ないなと気づいたので、実際にやってみた。

composer package という tarball のようなものは存在しない

meetup が始まる前にこの辺は調べがついていて、なんとなくそうなんじゃないかなーと思っていたけど、composer って

  • 依存性解決を行うけど
  • アーカイブは導入しない

という考え方になっている。

じゃあ packagist.org って何ってことになるんだけど、これは単に公開されている VCS とヒモ付けを行って、composer の search や install を助けてくれるだけのものとなっている。

デメリット

実際の install は単に github から clone してるだけだったりする。ということは、deploy 時に composer install を行おうと思ったら例えば github.com も packagist.org も両方生きていなければいけないということになる。これは deploy の信頼性を考える場合にデメリットにもなり得る。

repositories という記述を追加することで mirror を参照させることもできるので対策は打てるけど、Bundler のようにまとめて source を追加、切り替えられるわけではないので、マジメに考えるとちょっと面倒くさそうではある。

(例えば Sqale.jp という PaaS は gem を mirror してそっちを見にいくようにしている。Ruby アプリが増えれば増えるほど bundle install は帯域的につらくなりそうなので、これは正しいアプローチだと思う。こういうのは Gemfile なら簡単だけど composer.json だと大変そう。なんか方法あるのかな。)

メリット

この方式のメリットは、VCS への commit, push とパッケージの登録作業を別々に行う必要がないということ。バージョンは単に VCS 上のタグで表現される。

ということは package 登録作業者を packagist.org 上で collaborator 登録するということも必要なくなる。例えば github の organization で開発を行っているのであれば、そこに push できる人は全員 package の更新にも参加していることになるわけだ。そういう意味では管理はとても楽。

実際の登録、というか

前置きが長くなってしまったが、要は登録作業なんてものは存在しないので、やることは本当に少ない。

今回自分がやったのは

  • packagist.org にアカウント作成
  • packagist.org 上で github.com の repository 情報を追加
  • github.com の webhook に packagist.org の credential を追加

以上である。実際にやった結果は

wtnabe/ga-shikomi-php - Packagist

で、リポジトリは

wtnabe/ga-shikomi-php

えーとこれの説明はしたっけ。してないよね。まぁいいや。時間がないのでまた今度。

おまけ : minimum-stability

これは単に依存の記述次第なんだけど、例えば

symfony/console - Packagist

の場合、しばらく x.x.x-dev みたいなのが並んでいるので、自分はこれが正式版なのかなと思っていたけど、これは違うのね。あくまで dev バージョンの記述。

で、これに

require

で依存しちゃうと、stability の問題で通常は install できなくなってしまう。この問題については以下のブログ記事が詳しい。

Composerがパッケージのstabilityを解決するしくみ - オープンソースこねこね

require-dev

での依存ならオッケーだけど、require は stable が基本なので、そのままだと install できなくなってしまう。これを書いている時点では上の ga-shikomi-php も

"minimum-stability": "dev"

を追加しないと動かない。分かってしまえば「あぁ、そういや Pear も beta が install できなかったな」と思い出すこともできるんだけど。

ただ問題は

no matching package found.

とか、エラーメッセージが依存しているバージョンの stability の問題という意味に取れない場合があること。

ということで注意事項として改めてメモしておく。

おまけその2

The Twelve-Factor App を参照しつつ、開発者のレベルを上げていきましょうという発表を行った。まだ方法練ってないけど 12-factor を参考にしつつ具体的な改善を考えたりする勉強会というか Kanazawa.rb 内のサークルみたいなものを始めようと思っている。

おまけその3

この日時点で CF 作成実績 489 個、もうすぐ Mind Controller Silver になり、L10 のメダル要件が揃うところまできた。

ということで packagist 登録もできて Ingress もできてビールがうまかったぜ!

Tags: PHP Composer