[ruby-on-rails] 내 코드에서 레일스 개발 환경에 대한 ENV 변수를 설정할 수 있습니까?
bash에서 내 ENV 변수를 다음을 통해 설정할 수 있음을 알고 있습니다.
export admin_password = "secret"
그러나 내 레일 소스 코드에서 어딘가에 할 수있는 방법이 있습니까? 내 첫 번째 시도는environment/development.rb
ENV['admin_password'] = "secret"
하지만 작동하지 않았습니다. 이를 수행하는 방법이 있습니까?
답변
[최신 정보]
“이전 답변”아래의 해결책이 일반적인 문제에 적용되지만이 섹션은 귀하의 의견을 명확히 한 후 특정 질문에 답변하는 것입니다.
질문에 지정한 것과 똑같이 환경 변수를 설정할 수 있어야합니다. 예를 들어 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 마크 업이 포함될 수 있습니다.)
답변
민감한 정보 (계정 자격 증명, 암호 등)를 하드 코딩하지 마십시오 . 대신 해당 정보를 환경 변수 (키 / 값 쌍)로 저장하는 파일을 만들고 해당 파일을 소스 코드 관리 시스템에서 제외합니다. 예를 들어 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'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 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
Foreman 및 .env
많은 개발자가 Foreman ( Heroku Toolbelt 와 함께 설치됨 ) 을 사용하여 앱을 로컬 에서 실행합니다 (Apache / Passenger 또는 같은 것을 사용하는 것과 반대 rails server
). Foreman과 Heroku Procfile
는 애플리케이션 에서 실행되는 명령을 선언하는 데 사용 하므로 로컬 개발에서 Heroku 로의 전환은 이와 관련하여 원활합니다. 저는 모든 Rails 프로젝트에서 Foreman과 Heroku를 사용하므로이 편리함이 좋습니다. 하지만 여기에 문제가 있습니다. Foreman /.env
은 dotenv 를 통해 저장된 환경 변수를로드 하지만 불행히도 dotenv는 본질적으로 key=value
쌍에 대한 파일 만 구문 분석합니다.; 이러한 쌍은 바로 거기에서 변수가되지 않으므로 이미 설정된 변수를 참조 할 수 없으며 (DRY를 유지하기 위해) 거기에서 “Ruby”를 수행 할 수 없습니다 (위의 조건문에서 언급했듯이). 에서 수행하십시오 /config/app_environment_variables.rb
. 예를 들어, DRY를 유지하는 측면에서 때때로 다음과 같은 작업을 수행합니다.
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
위에서 설명한 접근 방식 과 함께 Foreman을 사용 합니다.
답변
내 질문에서 이것을 시도하는 방식이 실제로 작동합니다!
# environment/development.rb
ENV['admin_password'] = "secret"
서버를 다시 시작해야했습니다. reload!
Rails 콘솔에서 실행하는 것으로 충분 하다고 생각 했지만 웹 서버도 다시 시작해야했습니다.
ENV 변수를 넣고 설정하는 것이 더 좋은 곳이라고 생각하기 때문에 내 대답을 선택하고 있습니다.
답변
답변
가장 좋은 방법은 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'
답변
시스템 환경과 레일의 환경은 다릅니다. ENV
Rails의 환경으로 작업 해 보겠습니다.하지만 런타임에 시스템 환경을 변경하려는 경우 명령을 백틱으로 묶을 수 있습니다.
# ruby code
`export admin_password="secret"`
# more ruby code
답변
스크립트 사용자 정의의 로딩을위한 .env
파일을 다음 줄을 추가 /config/environment.rb
사이, require
라인 및 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 솔루션 기반)