Wiem, że mogę ustawić zmienne ENV w bash za pośrednictwem
export admin_password = "secret"
Ale czy jest sposób, aby to zrobić gdzieś w kodzie źródłowym moich railsów? Moja pierwsza próba była takaenvironment/development.rb
ENV['admin_password'] = "secret"
Ale to nie zadziałało. Czy jest na to sposób?
export admin_password="secret"
, nieexport admin_password = "secret"
.Odpowiedzi:
[Aktualizacja]
Chociaż rozwiązanie w sekcji „stara odpowiedź” będzie działać w przypadku ogólnych problemów, w tej sekcji należy odpowiedzieć na konkretne pytanie po wyjaśnieniu zawartym w komentarzu.
Powinieneś być w stanie ustawić zmienne środowiskowe dokładnie tak, jak określono 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 zrestartować serwera, aby konfiguracja została ponownie załadowana!
[Stara odpowiedź]
W przypadku konfiguracji obejmującej całą aplikację można rozważyć następujące rozwiązanie:
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ące elementy: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, z dowolnego miejsca w aplikacji, możesz uzyskać dostęp
APP_CONFIG[:admin_password]
wraz ze wszystkimi innymi danymi. (Zauważ, że ponieważ inicjator zawieraERB.new
, twój plik YAML może zawierać znaczniki ERB).źródło
dev_environment.rb
kod i zastępując go moim, z przyjemnością zaznaczyłbym twoją odpowiedź, która jest znacznie dokładniejsza.config/environments/development.rb
pliku?Nigdy nie zakoduj na stałe poufnych informacji (danych logowania do konta, haseł itp . ) . Zamiast tego utwórz plik do przechowywania tych informacji 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'
Oprócz tego dodaj następujące wiersze
/config/environment.rb
międzyrequire
wierszem aApplication.initialize
wierszem:# 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)
Otóż to!
Jak mówi powyższy komentarz, robiąc to, wcześniej załadujesz swoje zmienne środowiskowe
environments/*.rb
, co oznacza, że będziesz mógł odwoływać się do swoich zmiennych w tych plikach (npenvironments/production.rb
.). Jest to duża zaleta w stosunku do umieszczania pliku zmiennych środowiskowych w środku/config/initializers/
.Wewnątrz
app_environment_variables.rb
nie ma potrzeby rozróżniania środowisk, jeśli chodzi o rozwój lub produkcję, ponieważ nigdy nie zapiszesz tego pliku do systemu zarządzania kodem źródłowym, dlatego jest on domyślnie przeznaczony dla kontekstu programowania . Ale jeśli chcesz ustawić coś specjalnego dla środowiska testowego (lub na okazje, kiedy testujesz lokalnie testujesz tryb produkcyjny ), po prostu dodaj blok warunkowy poniżej wszystkich innych zmiennych: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
Po każdej aktualizacji
app_environment_variables.rb
uruchom ponownie serwer aplikacji. Zakładając, że korzystasz z Apache / Passenger lubrails server
:W swoim kodzie odwołaj się do zmiennych środowiskowych 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 określić wartości logiczne i liczby jako łańcuchy (np.ENV['SEND_MAIL'] = 'false'
Nie tylkofalse
, iENV['TIMEOUT'] = '30'
nie tylko30
), w przeciwnym razie otrzymasz odpowiednio błędycan't convert false into String
ican't convert Fixnum into String
.Przechowywanie i udostępnianie poufnych informacji
Ostatnim węzłem do zawiązania jest: jak udostępnić te poufne informacje swoim klientom i / lub partnerom? W celu zapewnienia ciągłości biznesowej (tj. Gdy zostaniesz trafiony spadającą gwiazdą, w jaki sposób Twoi klienci i / lub partnerzy wznowią pełne działanie witryny?) Twoi klienci i / lub partnerzy muszą znać wszystkie poświadczenia wymagane przez Twoją aplikację . Wysyłanie e-maili / Skypowanie się z takimi rzeczami jest niebezpieczne i prowadzi do nieładu. Przechowywanie go w udostępnionych Dokumentach Google nie jest złe (jeśli wszyscy używają https), ale aplikacja przeznaczona do przechowywania i udostępniania drobiazgów, takich jak hasła, byłaby idealna.
Jak ustawić zmienne środowiskowe w 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 w 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 Foreman (instalowanego z Heroku Toolbelt ) do uruchamiania swoich aplikacji lokalnie (w przeciwieństwie do Apache / Passenger lub
rails server
). Foreman i Heroku używająProcfile
do zadeklarowania, jakie polecenia są uruchamiane przez twoją aplikację , więc przejście z lokalnego dewelopera do Heroku jest płynne w tym względzie. Używam Foreman i Heroku w każdym projekcie Rails, więc ta wygoda jest świetna. Ale o to chodzi ... Foreman ładuje zmienne środowiskowe przechowywane/.env
przez dotenv, ale niestety dotenv zasadniczo analizuje plik tylko pod kątemkey=value
par; te pary nie stają się zmiennymi od razu tam i wtedy, więc nie możesz odwoływać się do już ustawionych zmiennych (aby utrzymać rzeczy SUCHE), ani nie możesz tam zrobić "Ruby" (jak wspomniano powyżej z warunkami), które możesz zrobić w/config/app_environment_variables.rb
. Na przykład, jeśli chodzi o utrzymywanie rzeczy SUCHA, 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 moich aplikacji lokalnie, ale nie używam jego
.env
pliku do ładowania zmiennych środowiskowych; raczej używam Foremana w połączeniu z/config/app_environment_variables.rb
podejściem opisanym powyżej.źródło
Sposób, w jaki próbuję to zrobić w moim pytaniu, faktycznie działa!
# environment/development.rb ENV['admin_password'] = "secret"
Musiałem tylko zrestartować serwer. Myślałem, że
reload!
wystarczy uruchomić w konsoli rails, ale musiałem też zrestartować serwer WWW.Wybieram własną odpowiedź, ponieważ uważam, że jest to lepsze miejsce do umieszczania i ustawiania zmiennych ENV
źródło
config/application.rb
iconfig/environments/*.rb
konfigurować środowisko Railsów oraz używać innych metod do konfigurowania środowiska aplikacji , ale to z pewnością nie oznacza, że jest to jedyny sposób (ani nawet „właściwy” sposób :)Poza rozwiązaniami tutaj, istnieją czystsze alternatywy, jeśli używasz niektórych serwerów programistycznych.
Z Heroku's Foreman , możesz tworzyć zmienne środowiskowe dla projektu w
.env
pliku:ADMIN_PASSOWRD="secret"
Z Pow możesz użyć
.powenv
pliku:export ADMIN_PASSOWRD="secret"
źródło
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 intializera
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 w pliku Yml:
development: app_key: 'abc' app_secret: 'abc' production: app_key: 'xyz' app_secret: 'ghq'
źródło
Środowisko systemowe i środowisko szyn to różne rzeczy.
ENV
pozwól nam pracować ze środowiskiem railsów, ale jeśli to, co chcesz zrobić, to zmienić środowisko systemu w czasie wykonywania, możesz po prostu otoczyć polecenie lewymi apostrofami.# ruby code `export admin_password="secret"` # more ruby code
źródło
export
będzie narzekać na spacje; spróbujexport admin_password="secret"
Skrypt do ładowania
.env
pliku niestandardowego : Dodaj następujące wiersze do/config/environment.rb
, międzyrequire
wierszem aApplication.initialize
wierszem:# 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
) będzie wyglądać tak:# This is ignored comment DATABASE_URL=mysql2://user:[email protected]:3307/database RACK_ENV=development
(Na podstawie rozwiązania @ user664833)
źródło