コードでRails開発環境のENV変数を設定することはできますか?


83

ENV変数をbashで設定できることを知っています。

export admin_password = "secret"

しかし、私のRailsソースコードのどこかにそれを行う方法はありますか?私の最初の試みはこのようなものでしたenvironment/development.rb

ENV['admin_password'] = "secret"

しかし、それはうまくいきませんでした。これを行う方法はありますか?


1
bashコマンドは。export admin_password="secret"ではなく、である必要があることに注意してくださいexport admin_password = "secret"
JacobLockard20年

回答:


81

[更新]

「古い答え」の下の解決策は一般的な問題に対しては機能しますが、このセクションでは、コメントから明確にした後、特定の質問に答えます。

質問で指定したとおりに環境変数を設定できるはずです。例として、HTTP基本認証を使用するHerokuアプリがあります。

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :authenticate

  def authenticate
    authenticate_or_request_with_http_basic do |username, password|
      username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
    end
  end
end

# config/initializers/dev_environment.rb
unless Rails.env.production?
  ENV['HTTP_USER'] = 'testuser'
  ENV['HTTP_PASS'] = 'testpass'
end

だからあなたの場合はあなたが使うでしょう

unless Rails.env.production?
  ENV['admin_password'] = "secret"
end

構成が再ロードされるように、サーバーを再起動することを忘れないでください!

【旧回答】

アプリ全体の構成では、次のようなソリューションを検討できます。

config/application.ymlアクセスできるようにするオプションのハッシュを使用してファイルを作成します。

admin_password: something_secret
allow_registration: true
facebook:
  app_id: application_id_here
  app_secret: application_secret_here
  api_key: api_key_here

次に、ファイルconfig/initializers/app_config.rbを作成し、以下を含めます。

require 'yaml'

yaml_data = YAML::load(ERB.new(IO.read(File.join(Rails.root, 'config', 'application.yml'))).result)
APP_CONFIG = HashWithIndifferentAccess.new(yaml_data)

これで、アプリケーションのどこからでも、APP_CONFIG[:admin_password]他のすべてのデータとともににアクセスできます。(イニシャERB.newライザーにはが含まれているため、YAMLファイルにERBマークアップを含めることができることに注意してください。)


2
ええと、私はHerokuを使用しており、ソース管理にチェックインしたくないパスワードなどのいくつかのENV変数を設定できます。私は自分の開発マシンで行う最善のことを見つけようとしています。はい、アプリ内のデータを使用しようとしています。
Lan

それを聞いてうれしい!答えが正しいと感じた場合は、質問の横にあるチェックマークをオンにしてマークを付ける必要があります。それはあなたと回答者の評判を獲得し、また将来この質問を見つけた人々が正しい答えを見つけるのを助けます。
ミシェルティリー2011

そうそう、私は新しいユーザーなので、確認できるようになるまで19時間待たされます。あと3時間です:)でも、助けてくれてありがとう!実際、dev_environment.rbコードを削除して自分のものに置き換える際に回答を編集する場合は、はるかに徹底的な回答に喜んでマークを付けます。
Lan

私はこれが好きですが、何らかの理由(rails 3 v 4?)でapp_config.rbをロードできませんでした。コードをconfig / environment.rbに入れて、同じ効果を得ました。#Railsアプリケーションをロードするrequire File.expand_path( '../ application'、FILE)require'yaml 'yaml_data = YAML :: load(ERB.new(IO.read(File.join(Rails.root、' config '、 'local_env.yml')))。result)APP_CONFIG = HashWithIndifferentAccess.new(yaml_data)#railsアプリケーションを初期化しますRails3 :: Application.initialize!
ベン

そのような古いスレッドを開いて申し訳ありませんが、開発環境に固有の設定はconfig/environments/development.rbファイルでより意味がありませんか?
jeffdill2 2015

130

機密情報(アカウントの資格情報、パスワードなど)をハードコーディングしないでください。代わりに、その情報を環境変数(キーと値のペア)として保存するファイルを作成し、そのファイルをソースコード管理システムから除外します。たとえば、Git(ソースコード管理システム)の観点から、そのファイルをに追加して除外します。gitignore

-bash> echo '/config/app_environment_variables.rb' >> .gitignore 

/config/app_environment_variables.rb

ENV['HTTP_USER'] = 'devuser'
ENV['HTTP_PASS'] = 'devpass'

同様に、次の行を/config/environment.rbrequire行と行の間に追加しますApplication.initialize

# Load the app's custom environment variables here, so that they are loaded before environments/*.rb
app_environment_variables = File.join(Rails.root, 'config', 'app_environment_variables.rb')
load(app_environment_variables) if File.exists?(app_environment_variables)

それでおしまい!

上記のコメントが言うように、これを行うことにより、前environments/*.rbに環境変数をロードすることになります。つまり、これらのファイル内の変数を参照できるようになります(例environments/production.rb)。これは、環境変数ファイルをに入れるよりも大きな利点です/config/initializers/

内部app_environment_variables.rbでは、このファイルをソースコード管理システムにコミットすることは決してないため、開発または本番まで環境を区別する必要はありません。したがって、デフォルトでは開発コンテキスト用です。ただし、テスト環境(または本番モードをローカルでテストする場合)に特別なものを設定する必要がある場合は、他のすべての変数の下に条件付きブロックを追加するだけです。

if Rails.env.test?
  ENV['HTTP_USER'] = 'testuser'
  ENV['HTTP_PASS'] = 'testpass'
end

if Rails.env.production?
  ENV['HTTP_USER'] = 'produser'
  ENV['HTTP_PASS'] = 'prodpass'
end

更新するたびにapp_environment_variables.rb、アプリサーバーを再起動してください。Apache / Passengerなどを使用していると仮定しますrails server

-bash> touch tmp/restart.txt

コードで、次のように環境変数を参照します。

def authenticate
  authenticate_or_request_with_http_basic do |username, password|
    username == ENV['HTTP_USER'] && password == ENV['HTTP_PASS']
  end
end

内部app_environment_variables.rbでは、ブール値数値文字列として指定する必要があることに注意してください(たとえばENV['SEND_MAIL'] = 'false'、だけfalseでなく、だけではありENV['TIMEOUT'] = '30'ません30)。そうしないcan't convert false into Stringcan't convert Fixnum into String、それぞれエラーとが発生します。

機密情報の保存と共有

最後の結び目は、この機密情報をクライアントやパートナーと共有する方法です。ビジネス継続性の目的で(つまり、流れ星に見舞われた場合、クライアントやパートナーはどのようにしてサイトの完全な運用を再開しますか?)、クライアントやパートナーはアプリに必要なすべての資格情報を知っている必要があります。これらのものを電子メールで送信/スキップすることは安全ではなく、混乱を招きます。共有のGoogleドキュメントに保存するのは悪くありませんが(全員がhttpsを使用している場合)、パスワードなどの小さな情報を保存して共有するための専用アプリが理想的です。

Herokuで環境変数を設定する方法

Herokuに単一の環境がある場合:

-bash> heroku config:add HTTP_USER='herouser'
-bash> heroku config:add HTTP_USER='heropass'

Herokuに複数の環境がある場合:

-bash> heroku config:add HTTP_USER='staguser' --remote staging
-bash> heroku config:add HTTP_PASS='stagpass' --remote staging

-bash> heroku config:add HTTP_USER='produser' --remote production
-bash> heroku config:add HTTP_PASS='prodpass' --remote production

フォアマンと.env

多くの開発者は、(Apache / Passengerなどを使用するのではなく)ForemanHeroku Toolbeltとともにインストール)を使用してアプリをローカルで実行しますrails server。ForemanとHerokuはProcfile、アプリケーション実行されるコマンドを宣言するために使用するため、ローカル開発からHerokuへの移行はその点でシームレスです。私はすべてのRailsプロジェクトでForemanとHerokuを使用しているので、この便利さは素晴らしいです。しかし、これが問題です。Foremanはdotenv/.env介して格納された環境変数をロードしますが、残念ながら、dotenvは基本的にファイルのkey=valueペアのみを解析します。; それらのペアはその場で変数にならないので、すでに設定されている変数を参照することはできません(物事をドライに保つため)。また、そこで「Ruby」を実行することもできません(上記の条件文で説明)。で行います/config/app_environment_variables.rb。たとえば、物事を乾いた状態に保つという点で、私は時々次のようなことをします:

ENV['SUPPORT_EMAIL']='Company Support <support@company.com>'
ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL']
ENV['MAILER_DEFAULT_TO']   = ENV['SUPPORT_EMAIL']

したがって、Foremanを使用してアプリをローカルで実行し.envますが、そのファイルを環境変数の読み込みには使用しません。むしろ、私/config/app_environment_variables.rbは上記のアプローチと組み合わせてフォアマンを使用します。


3
機密設定(APIキーなど)がクリアテキストではなくキーストアで適切に保護され、Gitリポジトリにバンドルされていないことを確認したかったので、このソリューションが好きです。ありがとう。
Rori Stumpf 2012年

10

私の質問でこれを行おうとしている方法は実際に機能します!

# environment/development.rb

ENV['admin_password'] = "secret" 

サーバーを再起動する必要がありました。reload!Railsコンソールで実行するだけで十分だと思いましたが、Webサーバーも再起動する必要がありました。

これはENV変数を配置および設定するのに適した場所だと思うので、私は自分の答えを選んでいます


なぜそれが機能しなかったのかを知ってうれしいです!私は個人的に、Rails環境を保存config/application.rbconfig/environments/*.rbてセットアップしたり、他の方法を使用してアプリケーション環境をセットアップしたりするのが好きですが、それが唯一の方法(または「正しい」方法です:)
Michelle Tilley

制作と開発で物事を変えようとしていたので、少しがっかりしました。しかし今、私はあなたに完全に同意します!元の質問に答えるだけでなく、railsアプリの構造をよりよく理解するのを手伝ってくれてありがとう!
Lan

8

ここでの解決策とは別に、特定の開発サーバーを使用している場合は、よりクリーンな代替手段があります。

HerokuのForemanを使用すると、プロジェクトごとの環境変数を.envファイルに作成できます。

ADMIN_PASSOWRD="secret"

ではパウは、使用することができます.powenvファイルを:

export ADMIN_PASSOWRD="secret"

2

最善の方法は、それらをymlファイルに保存してから、このコマンドを使用してinitializerファイルにそのファイルをロードすることだと思います。

APP_CONFIG = YAML.load_file("#{Rails.root}/config/CONFIG.yml")[Rails.env].to_hash

環境関連の構成変数に簡単にアクセスできます。

Ymlファイルのキー値構造:

development:
  app_key: 'abc'
  app_secret: 'abc'

production:
  app_key: 'xyz'
  app_secret: 'ghq'

1

システム環境とレールの環境は別物です。ENVRailsの環境で作業してみましょう。ただし、実行時にシステムの環境を変更する場合は、コマンドをバッククォートで囲むことができます。

# ruby code
`export admin_password="secret"`
# more ruby code

1
exportスペースについて文句を言うだけのメモ。試してみてくださいexport admin_password="secret"
ミシェルティリー2011

その(非常に重要な)詳細を忘れました。私の答えを訂正しました、ありがとう!
goncalossilva 2011

バックティックはサブシェルを生成し、サブシェルで設定した変数は親の環境に影響を与えないため、これは機能しません。
AndrewF 2013

いいえ、機能します。明確に説明されているように、答えは親の環境を対象としていません。それを行う方法を指示する完全に良い答えがあります。
goncalossilva 2013

1

カスタム.envファイルをロードするためのスクリプト:次の行を/config/environment.rbrequire行と行の間に追加しますApplication.initialize

# Load the app's custom environment variables here, so that they are loaded before environments/*.rb

app_environment_variables = File.join(Rails.root, 'config', 'local_environment.env')
if File.exists?(app_environment_variables)
  lines = File.readlines(app_environment_variables)
  lines.each do |line|
    line.chomp!
    next if line.empty? or line[0] == '#'
    parts = line.partition '='
    raise "Wrong line: #{line} in #{app_environment_variables}" if parts.last.empty?
    ENV[parts.first] = parts.last
  end
end

そしてconfig/local_environment.env(あなたは.gitignoreそれをしたいと思うでしょう)次のようになります:

# This is ignored comment
DATABASE_URL=mysql2://user:psw@0.0.0:3307/database
RACK_ENV=development

(@ user664833のソリューションに基づく)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.