環境
Ruby2.6
Rails5.2
Ubuntu20.4
はじめに
RDBに接続する時のユーザーIDとパスワードは、database.ymlで設定します。しかし、database.ymlで設定すれば、GitHubに上げた時に、誰でも閲覧可能な状態にさらしてしまうことになります。これはセキュリティ上よくありません。それを防ぐためには、database.ymlをGitHubに上げなけばいいだけの話ではありますが、database.ymlには、ユーザーIDとパスワードの他にも、RDBの接続に関する重要な情報が含まれており、開発環境を再構築するためには、GitHubには置いておかなくてはいけないファイルになります。そこでよく使われる方法が、ユーザーIDとパスワードを環境変数に設定して、環境変数のキーをdatabase.ymlに設定する方法です。この方法をとれば、database.ymlをGitHubに上げても、ユーザーIDとパスワードが外部にさらされることはありません。Railsで環境変数を管理ときは、dotenvというgemが一般的に知られています。そこで、dotenvの使い方について書いてみました。
dotenvをインストールする
Rubyで環境変数を管理する場合は、dotenvというgemを使いますが、Railsで環境変数を管理する場合は、dotenvではなく、dotenv-railsを使います。Ruby単体でdotenvを使う場合は、次のようにインストールします。Railsで使う場合は、Gemfileに、gem 'dotenv-rails'を追加して、bundle installを実行します。
$gem install deoenv
dotenv(もしくは、dotenv-rails)をインストールした後、.envファイルを新規作成して、ファイルの中で環境変数を設定します。
DATABASE_USER=hoge_usr
DATABASE_PASS=hoge_pwd
Rubyで環境変数を取得する
Rubyからdotenvを使って環境変数を取得する場合です。
require 'dotenv'
Dotenv.load
puts ENV["DATABASE_USER"] # =>hoge_usr
puts ENV["DATABASE_PASS"] # =>hoge_pwd
.envファイルに環境変数を設定すれば、OSが持っている環境変数に書き込まれるのかといえば、そうではありません。.envファイルで設定した環境変数を、OSに問い合わせても、OSは値を持っていません。
$echo $DATABASE_PASS # => (空)
$echo $DATABASE_USER # => (空)
.envファイルに値をセットすることを「環境変数を設定する」という言い方をしますが、厳密にいえば、この表現には多少の語弊が含まれます。遠回しないい方にはなりますが、.envという名前のテキストファイルにOSに環境変数を設定するときと同じ記述の仕方をして、Rubyの環境変数を取り出すメソッドを使って、OSが持っている環境変数を取り出す方法と同じやり方で、.envファイルの値を取り出せるといった言い方のが妥当です。
dotenvを使わずに、自分で適当な名前のiniファイルを作成して、iniファイルに記述した値を、File.Openメソッドなどを使って取得しても、やっていることは大きく変わっていません。そもそも、.envファイルはOSの環境変数には現実的に何の影響も与えていません。しかし、後からコードを見直した時に、何をやっているのかを素早く理解するためにも、dotenvを利用した方が便利であることは確かです。
OSの環境変数に実際に設定されている、HOMEの値を取得する場合です。この時は、dotenvを使うことなく取得できます。
puts ENV["HOME"] # =>/home/tana
$echo $HOME # =>/home/tana
環境変数に設定されていない変数(キー)を取得した場合は、nilが返ってきます。環境変数が設定されていればその値を取得するが、設定されていなければ、代わりにデフォルト値をセットしたいといった場合は、次のようになります。fetchメソッドを使った方がスマートでしょう。
puts ENV["HOGE"].nil? ? "hoge_def" : ENV["HOGE"] # => hoge_def
puts ENV.fetch("HOGE"){"hoge_def"} # => hoge_def
Railsで環境変数を取得する
.envで設定した環境変数が、Railsで本当に取得できるのかを、Rails cで確認することができます。Ruby単体で使う場合と同じように、最初に、Dotenv.loadを実行しないと、取得できない点が注意です。
$rails c
>Dotenv.load
>ENV["DATABASE_USER"]
hoge_usr
database.ymlで設定する、ユーザーIDとパスワードを、.envファイルに記述して、database.ymlには環境変数をセットする場合の書き方です。rails sでアプリを起動する場合、config/application.rbで、Dotenv.loadを明示的に記述しなくても大丈夫なのかと思うかも分かりませんが、記述しなくても環境変数は取得できます。恐らく、Railsの内部のどこかで、陰にDotenv.loadが実行されているものと思われます。
development:
<<: *default
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASS'] %>
# username: hoge_usr
# password: hoge_pwd
最後に
.envファイルでにRDBに接続するためのユーザーIDとパスワードを設定した後、.envファイルをGitHubにあげないよう、Gitの.ignoreファイルで指定する必要があります。GitHubには上げなくても、本番サーバーにデプロイする時は、当然、.envファイルは上げなくいといけません。