間違いがあったらご指摘ください。
何が起こった
コケるまでのところ
手許のマシンで Rails 5.2.0 を使って
$ rails new hoge
してアプリを作った。
ファイルは Git で管理しており,リモートリポジトリーに push していった。
リモートリポジトリーから本番サーバー(VPS)上に clone した。
コケるところ
本番サーバーにて。
$ rails console
は問題ない。
ところが
$ rails console -e production
だと例外
`validate_secret_key_base': Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit` (ArgumentError)
が出る。
あー,そういえば Rails 5.1 までのときも production 環境では環境変数 SECRET_KEY_BASE
が必要だったから,それに似た話か。
ともかく「rails credentials:edit
をやれ」と言っているみたいなので,そうしよう。
$ sudo rails credentials:edit
すると,
No $EDITOR to open file in.
と文句が出た。どうやら EDITOR
という環境変数で,使うテキストエディターを指定しておかなければならないようだ。
そこで,vim を使うことにして,
$ sudo EDITOR=vim rails credentials:edit
とやったら,今度は
ActiveSupport::MessageEncryptor::InvalidMessage
が出た。
これがさっぱり分からなかった。
原因は
Rails 5.2 が秘匿情報を扱う仕組みをよく理解していれば解決は早かったと思う。
秘匿情報を扱う仕組み
Rails には,secret_key_base
のような値や,SMTP のパスワードなど,漏れてはマズい情報を取り扱う仕組みがある。
何が問題かというと,そういう情報たちも Git 管理下のファイルに書きたいのだけれど,そうするとリポジトリーが見られる人にはバレてしまう,ということ。
そこで,Rails 5.2 では,そういう情報を記述したテキストを暗号化し,その暗号化したファイルを Git で管理できるようにしている。
そしてその暗号を解くための鍵だけは Git 管理せずに取り扱う。
どうもそういうことらしい。
具体的に言うと,暗号化したあとのファイルは config/credentials.yml.enc
に保存される。ファイル名で分かるとおり,YAML 形式で記述して暗号化したものだ。
鍵のほうは環境変数 RAILS_MASTER_KEY
で与えるか,あるいは config/master.key
ファイルで与える。
rails credentials:edit
というのは,暗号化したファイルを復号して,指定のエディターで編集させ,その結果を再び暗号化して config/credentials.yml.enc
に保存するためのコマンドらしい。
で,なんでエラー?
rails new
すると,config/credentials.yml.enc
も config/master.key
も自動的に作られる。
config/master.key
のほうは,.gitignore
によって,Git 管理せぬよう指定されている。
よって,本番サーバー上でプロジェクトのリポジトリーを clone しても,このファイルは付いてこないわけだ。
つまり,この状態では本番サーバー上で暗号化ファイルが復号できない。だから secret_key_base
の値も得られない。
と,そういうことのようだ。
そこで,rails credentials:edit
を促されるわけだが,このコマンドは,鍵が存在しないとき,勝手に鍵を生成して config/master.key
に保存してくれちゃったりするらしい。
ところが,新しく生成された鍵は,既存の config/credentials.yml.enc
の復号には当然ながら使えない。
玄関の鍵を紛失して,鍵屋が別の鍵を持ってきても開くわけないものな。
それが
ActiveSupport::MessageEncryptor::InvalidMessage
の言わんとすることらしい。
解決
原因が分かったので,rails new
した環境の config/master.key
の中身をコピーして,本番サーバーの config/master.key
に持ってきた。
これで本番サーバーでも production 環境で動くようになった。
参考(追記)
Rails5.2から追加された credentials.yml.enc のキホン
master.key を紛失したらどうなる?(2018-08-01 追記)
もし,鍵(master.key)を紛失してしまっていたらどうなるのか。
〔よくあるのが,新規のプロジェクトを生成したあと,リモートのリポジトリーに push し,元のファイルは削除して,改めてリモートから clone して開発を始めるような場合。〕
鍵が無かったらどうしようもない。だから絶対に無くしてはダメ。
ただ,例えば開発の初期で,credentials.yml に大したことが書かれておらず(secret_key_base
程度),捨ててもよいのであれば,再作成すればよい。
つまり,config/credentials.yml.enc
をいったん削除して,
$ sudo EDITOR=vim rails credentials:edit
のようにすれば,新しく config/credentials.yml.enc
が作られる。
このとき,config/master.key
は,存在していなければ作られるし,存在していればそれが使われる。
sudo について(2022-02-05 追記)
この記事ではコマンドに sudo
を付けたところがある。
もう何年も前なので正確に覚えていないが,sudo
が付いているのは,ディレクトリーに書き込みパーミションが無い本番サーバー上で実験したときのコマンドをその場で手元にコピペして記事に利用したからだったと思う。
この記事を参考に rails credentials:edit
を実行する方もいらっしゃると思うが,おそらくほとんどの場合,sudo
は要らないはず。
「何となく付ける sudo
」はしばしばろくな結果をもたらさないので,必要性をよく考えて判断していただけると嬉しい。