Czy w moim kodzie można ustawić zmienne ENV dla środowiska programistycznego rails?

Wiem, że mogę ustawić swoje zmienne ENV w bash poprzez

export admin_password = "secret"

Ale czy jest jakiś sposób, aby to zrobić w moim kodzie źródłowym rails? Moja pierwsza próba była taka w environment/development.rb

ENV['admin_password'] = "secret"
Ale nie zadziałało. Jest na to sposób?
Author: Lan, 2011-02-06

7 answers

[Update]

Podczas gdy rozwiązanie pod "stara odpowiedź" będzie działać dla ogólnych problemów, Ta sekcja ma odpowiedzieć na twoje konkretne pytanie po wyjaśnieniu z komentarza.

Powinieneś być w stanie ustawić zmienne środowiskowe dokładnie tak, jak podałeś w swoim pytaniu. Jako przykład mam aplikację Heroku, która używa podstawowego uwierzytelniania 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

Więc w Twoim przypadku użyłbyś

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

Nie zapomnij ponownie uruchomić serwera, aby konfiguracja była przeładowany!

[Stara Odpowiedź]

W przypadku konfiguracji dla całej aplikacji można rozważyć rozwiązanie takie jak:

Utwórz plik config/application.yml z Hashem opcji, do których chcesz mieć dostęp:

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

Teraz Utwórz plik config/initializers/app_config.rb i dołącz następujący plik:

require 'yaml'

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

Teraz, gdziekolwiek w aplikacji, możesz uzyskać dostęp APP_CONFIG[:admin_password], wraz z innymi danymi. (Zauważ, że ponieważ inicjalizacja zawiera ERB.new, Plik YAML może zawierać znaczniki ERB.)

 81
Author: Michelle Tilley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-13 20:02:28

Nigdy nie używaj poufnych danych (poświadczeń konta, haseł itp.). Zamiast tego utwórz plik przechowujący te informacje jako zmienne środowiskowe (pary klucz / wartość) i wyklucz ten plik z systemu zarządzania kodem źródłowym. Na przykład, jeśli chodzi o Git (system zarządzania kodem źródłowym), wyklucz ten plik dodając go do .gitignore :

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

/config / app_environment_variables.rb

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

Jak również, dodaj następujące wiersze do /config/environment.rb, pomiędzy linią require, a linią 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)
To jest to!

Jak mówi powyższy komentarz, w ten sposób będziesz ładował swoje zmienne środowiskowe przed environments/*.rb, co oznacza, że będziesz mógł odwoływać się do swoich zmiennych wewnątrz tych plików (np. environments/production.rb). Jest to ogromna zaleta nad umieszczeniem pliku zmiennych środowiskowych w /config/initializers/.

Wewnątrz app_environment_variables.rb nie ma potrzeby rozróżniania środowisk w zakresie rozwoju lub production ponieważ nigdy nie zatwierdzisz tego pliku do swojego systemu zarządzania kodem źródłowym, dlatego domyślnie jest on przeznaczony dla development context. Ale jeśli chcesz ustawić coś specjalnego dla środowiska test (lub dla okazji, gdy testujesz production mode lokalnie ), po prostu dodaj warunkowy blok poniżej wszystkie pozostałe zmienne:

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

Za każdym razem, gdy aktualizujesz app_environment_variables.rb, uruchom ponownie serwer aplikacji. Zakładając, że używasz [[17]}:

-bash> touch tmp/restart.txt

W kodzie zapoznaj się ze zmiennymi środowiskowymi w następujący sposób:

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

Zauważ, że wewnątrz app_environment_variables.rb musisz podać booleans I liczby jako ciągi (np. ENV['SEND_MAIL'] = 'false' nie tylko false, i ENV['TIMEOUT'] = '30' nie tylko 30), w przeciwnym razie otrzymasz odpowiednio błędy can't convert false into String i can't convert Fixnum into String.

Przechowywanie i udostępnianie poufnych informacji

Ostatnim węzłem do zawiązania jest: Jak dzielić te poufne informacje z klientami i / lub partnerami? W celu zapewnienia ciągłości działania (tj. gdy zostaniesz uderzony przez spadającą gwiazdę, w jaki sposób Twoi klienci i/lub partnerzy wznowią pełną działalność witryny?), twoi klienci i / lub partnerzy muszą znać wszystkie poświadczenia wymagane przez Twoją aplikację. Wysyłanie e-maili / Wysyłanie przez Skype ' a tych rzeczy jest niebezpieczne i prowadzi do chaosu. Przechowywanie go w udostępnionych Dokumentach Google nie jest złe (jeśli wszyscy używają https), ale aplikacja dedykowana do przechowywania i udostępniania małe cyce jak hasła byłyby idealne.

Jak ustawić zmienne środowiskowe na Heroku

Jeśli masz jedno środowisko na Heroku:

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

Jeśli masz wiele środowisk na 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

Foreman i .env

Wielu programistów używa Foremana (zainstalowanego z Heroku Toolbelt ) do uruchamiania swoich aplikacji lokalnie (W przeciwieństwie do korzystania z Apache/Passenger lub rails server). Foreman i HerokuProcfile do deklarowania, jakie polecenia są uruchamiane przez Twoją aplikację , więc przejście z lokalnego dev do Heroku jest bezproblemowe pod tym względem. Używam Foremana i Heroku w każdym projekcie Rails, więc ta wygoda jest świetna. Ale chodzi o to.. Foreman ładuje zmienne środowiskowe przechowywane w /.env przez dotenv ale niestety dotenv zasadniczo przetwarza plik tylko dla key=value par ; te pary nie stają się zmiennymi i następnie, więc nie możesz odwoływać się do już ustawionych zmiennych (aby wszystko było suche), ani nie możesz tam zrobić "Ruby" (jak wspomniano powyżej z warunkami), co możesz zrobić w /config/app_environment_variables.rb. Na przykład, jeśli chodzi o utrzymywanie rzeczy suchych, czasami robię takie rzeczy: {]}

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

Dlatego używam Foremana do uruchamiania aplikacji lokalnie, ale nie używam jego pliku .env do ładowania zmiennych środowiskowych; raczej używam Foremana w połączeniu z opisanym powyżej podejściem /config/app_environment_variables.rb.

 134
Author: user664833,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-28 22:47:55

Sposób, w jaki próbuję to zrobić w moim pytaniu, naprawdę działa!

# environment/development.rb

ENV['admin_password'] = "secret" 
Musiałem zrestartować serwer. Myślałem, że uruchomienie reload! w konsoli rails wystarczy, ale musiałem też ponownie uruchomić serwer WWW.

Wybieram własną odpowiedź, ponieważ uważam, że jest to lepsze miejsce, aby umieścić i ustawić zmienne ENV

 10
Author: Lan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-07 09:31:31

Poza rozwiązaniami tutaj, istnieją czystsze alternatywy, jeśli używasz niektórych serwerów deweloperskich.

Za pomocą Heroku ' s Foreman , możesz tworzyć zmienne środowiskowe dla poszczególnych projektów w pliku .env:

ADMIN_PASSOWRD="secret"

Z Pow , możesz użyć pliku .powenv:

export ADMIN_PASSOWRD="secret"
 8
Author: Aupajo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-06 03:50:13

Myślę, że najlepszym sposobem jest przechowywanie ich w jakimś pliku yml, a następnie załadowanie tego pliku za pomocą tego polecenia w pliku intializer

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

Możesz łatwo uzyskać dostęp do zmiennych konfiguracyjnych związanych ze środowiskiem.

Struktura wartości klucza pliku Yml:

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

production:
  app_key: 'xyz'
  app_secret: 'ghq'
 3
Author: Taimoor Changaiz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-06 10:54:30

Środowisko systemowe i środowisko rails to różne rzeczy. ENV Let 's you work with the rails' environment, but if you want to do to change the system ' s environment in runtime you can just surround the command with backticks.

# ruby code
`export admin_password="secret"`
# more ruby code
 1
Author: goncalossilva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-06 17:42:00

Skrypt do ładowania niestandardowego pliku .env: Dodaj następujące linie do /config/environment.rb, pomiędzy linią require, a linią 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

I config/local_environment.env (będziesz chciał .gitignore to) będą wyglądać następująco:

# This is ignored comment
DATABASE_URL=mysql2://user:[email protected]:3307/database
RACK_ENV=development

(na podstawie rozwiązania @user664833)

 1
Author: Daniel Garmoshka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-21 18:04:48