IT

내 코드에서 레일스 개발 환경에 대한 ENV 변수를 사용할 수 있습니까?

lottoking 2020. 10. 9. 08:38

내 코드에서 레일스 개발 환경에 대한 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.newYAML 파일에 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에서는 이 파일을 소스 코드 관리 시스템에 커밋하지 않기 때문에 개발 또는 프로덕션에 관한 Environmental &을 구분할 필요 가 없으므로 기본적으로 개발 컨텍스트 입니다. 그러나 테스트 Environmental & (또는 로컬에서 프로덕션 -mode 를 테스트하는 경우)에 대해 특별한 것을 설정 해야하는 경우 다른 모든 변수 아래에 보기 조건 블록을 추가하기 만하면 됩니다 .

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

Note that inside app_environment_variables.rb you must specify booleans and numbers as strings (e.g. ENV['SEND_MAIL'] = 'false' not just false, and ENV['TIMEOUT'] = '30' not just 30), otherwise you will get the errors can't convert false into String and can't convert Fixnum into String, respectively.

Storing and sharing sensitive information

마지막 매듭 점은 이 민감한 정보를 고객 및 / 또는 파트너와 공유하는 방법 입니다. 비즈니스 연속성을 위해 (즉, 낙하하는 별에 맞을 때 고객 및 / 또는 파트너가 사이트의 전체 운영을 어떻게 재개합니까?), 고객 및 / 또는 파트너는 앱에 필요한 모든 자격 증명을 알아야합니다. . 이러한 것들을 이메일로 전송 / 스카이 핑하는 것은 안전하지 않으며 혼란을 초래합니다. 공유 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 변수를 넣고 설정하는 것이 더 좋은 곳이라고 생각하기 때문에 내 대답을 선택하고 있습니다.


여기의 솔루션 외에도 특정 개발 서버를 사용하는 경우 더 깨끗한 대안이 있습니다.

Heroku의 Foreman을 사용하면 .env파일 에 프로젝트 별 환경 변수를 만들 수 있습니다 .

ADMIN_PASSOWRD="secret"

함께 , 당신은 사용할 수있는 .powenv파일 :

export ADMIN_PASSOWRD="secret"

가장 좋은 방법은 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'

시스템 환경과 레일의 환경은 다릅니다. ENVRails의 환경으로 작업 해 보겠습니다.하지만 런타임에 시스템 환경을 변경하려는 경우에는 명령을 백틱으로 둘러싸면됩니다.

# 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 솔루션 기반)

참고 URL : https://stackoverflow.com/questions/4911607/is-it-possible-to-set-env-variables-for-rails-development-environment-in-my-code