Подтвердить что ты не робот

Можно ли установить переменные ENV для среды разработки rails в моем коде?

Я знаю, что могу установить свои переменные ENV в bash через

export admin_password = "secret"

Но есть ли способ сделать это в моем исходном коде rails? Моя первая попытка была такой, как в environment/development.rb

ENV['admin_password'] = "secret"

Но это не сработало. Есть ли способ сделать это?

4b9b3361

Ответ 1

[Обновление]

В то время как решение под "старым ответом" будет работать для общих проблем, этот раздел должен ответить на ваш конкретный вопрос после разъяснения вашего комментария.

Вы должны иметь возможность устанавливать переменные среды точно так же, как вы указываете в своем вопросе. В качестве примера у меня есть приложение Heroku, которое использует базовую аутентификацию HTTP.

# 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

Никогда не защищайте конфиденциальную информацию (учетные данные, пароли и т.д.). Вместо этого создайте файл для хранения этой информации в качестве переменных среды (пары ключ/значение) и исключите этот файл из системы управления исходным кодом. Например, с точки зрения 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.rb, между строкой require и строкой Application.initialize:

# Load the app 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 String и can'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

Многие разработчики используют Foreman (установлен с Heroku Toolbelt) в запускать свои приложения локально (в отличие от использования Apache/Passenger или rails server). Foreman и Heroku используют Procfile для объявления, какие команды выполняются вашим приложением, поэтому переход от локального разработчика к Heroku в этом отношении невозможен. Я использую Foreman и Heroku в каждом проекте Rails, поэтому это удобство отлично. Но вот что.. Форман загружает переменные среды, хранящиеся в /.env через dotenv, но, к сожалению, dotenv по существу только анализирует файл для пар key=value; эти пары не становятся переменными прямо там и тогда, поэтому вы не можете ссылаться на уже установленные переменные (чтобы сохранить вещи DRY), и вы не можете сделать там "Ruby" (как указано выше с условными обозначениями), которые вы можете в /config/app_environment_variables.rb. Например, с точки зрения сохранения вещей DRY я иногда делаю такие вещи:

ENV['SUPPORT_EMAIL']='Company Support <[email protected]>'
ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL']
ENV['MAILER_DEFAULT_TO']   = ENV['SUPPORT_EMAIL']

Следовательно, я использую Foreman для запуска моих приложений локально, но я не использую его файл .env для загрузки переменных среды; скорее я использую Foreman в сочетании с описанным выше подходом /config/app_environment_variables.rb.

Ответ 3

В отличие от решений здесь есть более чистые альтернативы, если вы используете определенные серверы разработки.

С Heroku Foreman вы можете создавать переменные среды для каждого проекта в файле .env:

ADMIN_PASSOWRD="secret"

С Pow вы можете использовать файл .powenv:

export ADMIN_PASSOWRD="secret"

Ответ 4

Как я пытаюсь сделать это в своем вопросе, действительно работает!

# environment/development.rb

ENV['admin_password'] = "secret" 

Мне просто пришлось перезапустить сервер. Я думал, что запуск reload! в консоли rails будет достаточно, но мне также пришлось перезапустить веб-сервер.

Я выбираю свой собственный ответ, потому что считаю, что это лучшее место для установки и установки переменных ENV

Ответ 5

Я думаю, что лучший способ - хранить их в каком-то yml файле, а затем загружать этот файл с помощью этой команды в файле intializer

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'

Ответ 6

Среда и среда рельсов - это разные вещи. ENV позволяет работать с окружением рельсов, но если вы хотите изменить системную среду во время выполнения, вы можете просто окружить команду обратными окнами.

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

Ответ 7

Script для загрузки пользовательского файла .env: Добавьте следующие строки в /config/environment.rb, между строкой require и строкой Application.initialize:

# Load the app 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:[email protected]:3307/database
RACK_ENV=development

(На основе решения @user664833)