Kodumda ray geliştirme ortamı için ENV değişkenleri ayarlamak mümkün mü?


83

ENV değişkenlerimi bash ile ayarlayabileceğimi biliyorum.

export admin_password = "secret"

Ama bunu raylarımın kaynak kodunda bir yerde yapmanın bir yolu var mı? İlk denemem şunun gibi bir şeydi:environment/development.rb

ENV['admin_password'] = "secret"

Ama işe yaramadı. Bunu yapmanın bir yolu var mı?


1
Bash komutunun olması gerektiğini export admin_password="secret"unutmayın export admin_password = "secret".
Jacob Lockard

Yanıtlar:


81

[Güncelleme]

"Eski cevap" altındaki çözüm genel sorunlar için işe yarayacak olsa da, bu bölüm, yorumunuzdan sonra açıklama yaptıktan sonra özel sorunuzu cevaplamak içindir.

Ortam değişkenlerini tam olarak sorunuzda belirttiğiniz gibi ayarlayabilmelisiniz. Örnek olarak, HTTP temel kimlik doğrulamasını kullanan bir Heroku uygulamam var.

# 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

Yani senin durumunda kullanacaksın

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

Yapılandırmanın yeniden yüklenmesi için sunucuyu yeniden başlatmayı unutmayın!

[Eski Cevap]

Uygulama çapında yapılandırma için aşağıdaki gibi bir çözüm düşünebilirsiniz:

config/application.ymlErişmek istediğiniz seçeneklerin karması ile bir dosya oluşturun :

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

Şimdi dosyayı oluşturun config/initializers/app_config.rbve aşağıdakileri ekleyin:

require 'yaml'

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

Artık uygulamanızın herhangi bir yerinden APP_CONFIG[:admin_password]diğer tüm verilerinizle birlikte erişebilirsiniz . (Başlatıcı içerdiğinden ERB.new, YAML dosyanızın ERB işaretlemesi içerebileceğini unutmayın.)


2
Pekala, Ben Heroku kullanıyorum ve şifreler gibi kaynak kontrolünde kontrol edilmesini istemediğiniz şeyler için bazı ENV değişkenleri belirlemenize izin veriyorlar. Dev makinemde yapılacak en iyi şeyi bulmaya çalışıyorum. Ve evet, uygulamamın içindeki verileri kullanmaya çalışıyorum.
Lan

Duyduğuma sevindim! Bir cevabın doğru olduğunu düşünüyorsanız, sorunun yanındaki onay işaretini işaretleyerek işaretlemelisiniz. Size ve yanıtlayanın itibarını kazandıracak ve ayrıca bu soruyu gelecekte bulan kişilerin doğru yanıtı bulmalarına yardımcı olacaktır.
Michelle Tilley

Oh evet, ben yeni bir kullanıcıyım, bu yüzden kontrol etmeden önce 19 saat bekletiyorum. Hala 3 saat kaldı :) Ama yardımlarınız için teşekkürler! Aslında, dev_environment.rbkodu kaldırıp benimkiyle değiştirerek cevabınızı düzenlerseniz , çok daha kapsamlı olan cevabınızı memnuniyetle işaretlerim.
Lan

bunu beğendim ama bazı nedenlerden dolayı (rails 3 v 4?) app_config.rb dosyasını yükleyemedim. Kodu config / environment.rb içine koydum ve aynı etkiye sahip oldum. # Rayları yükleyin uygulaması, File.expand_path ('../ application', FILE ) gerektirir 'yaml' gerektirir yaml_data = YAML :: load (ERB.new (IO.read (File.join (Rails.root, 'config'), 'local_env.yml'))) sonuç) APP_CONFIG = HashWithIndifferentAccess.new (yaml_data) # Rails uygulamasını başlatın Rails3 :: Application.initialize!
Ben

Bu kadar eski bir iş parçacığını açtığım için üzgünüz, ancak geliştirme ortamına özgü bir ayar config/environments/development.rbdosyada daha anlamlı olmaz mı?
jeffdill2

130

Hassas bilgileri (hesap kimlik bilgileri, parolalar vb.) Asla kodlamayın . Bunun yerine, bu bilgileri ortam değişkenleri (anahtar / değer çiftleri) olarak depolamak için bir dosya oluşturun ve bu dosyayı kaynak kodu yönetim sisteminizden hariç tutun. Örneğin, Git (kaynak kodu yönetim sistemi) açısından, bu dosyayı ekleyerek hariç tutun. gitignore :

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

/config/app_environment_variables.rb

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

Ayrıca /config/environment.rb, requireçizgi ile çizgi arasına aşağıdaki satırları ekleyin 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)

Bu kadar!

Yukarıdaki yorumun dediği gibi, bunu yaparak ortam değişkenlerinizi daha önce yükleyeceksiniz environments/*.rb, bu da bu dosyaların içindeki değişkenlerinize başvurabileceğiniz anlamına gelir (örn. environments/production.rb). Bu, ortam değişkenleri dosyanızı içine koymaya göre büyük bir avantajdır /config/initializers/.

İçinde app_environment_variables.rb, geliştirme veya üretim açısından ortamları ayırt etmeye gerek yoktur çünkü bu dosyayı asla kaynak kodu yönetim sisteminize kaydetmeyeceksiniz, bu nedenle varsayılan olarak geliştirme bağlamı içindir. Ancak, test ortamı için (veya üretim modunu yerel olarak test ettiğiniz durumlar için) özel bir şey ayarlamanız gerekirse , diğer tüm değişkenlerin altına bir koşullu blok eklemeniz yeterlidir :

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

Her güncelleme yaptığınızda app_environment_variables.rb, uygulama sunucusunu yeniden başlatın. Apache / Passenger veya rails server:

-bash> touch tmp/restart.txt

Kodunuzda, aşağıdaki gibi ortam değişkenlerine bakın:

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

İçlerindeki Not app_environment_variables.rbbelirtmelisiniz Boolean ve sayılar olarak dizeleri (örneğin ENV['SEND_MAIL'] = 'false'sadece falseve ENV['TIMEOUT'] = '30'sadece 30,) aksi takdirde hatası alacağını can't convert false into Stringve can't convert Fixnum into Stringsırasıyla.

Hassas bilgileri saklama ve paylaşma

Bağlanması gereken son düğüm şudur: Bu hassas bilgileri müşterilerinizle ve / veya ortaklarınızla nasıl paylaşabilirsiniz? İş sürekliliği amacıyla (yani düşen bir yıldız tarafından vurulduğunuzda, müşterileriniz ve / veya ortaklarınız sitenin tüm işlemlerine nasıl devam edecek?), Müşterilerinizin ve / veya ortaklarınızın uygulamanızın gerektirdiği tüm kimlik bilgilerini bilmesi gerekir. . Bunları e-postayla göndermek / Skyping yapmak güvensizdir ve kargaşaya yol açar. Paylaşılan Google Dokümanlarında saklamak fena değildir (herkes https kullanıyorsa), ancak şifreler gibi küçük başlıkları depolamaya ve paylaşmaya adanmış bir uygulama ideal olacaktır.

Heroku'da ortam değişkenleri nasıl ayarlanır?

Heroku'da tek bir ortamınız varsa:

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

Eğer varsa çoklu ortamları Heroku tarih:

-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 ve .env

Birçok geliştirici , uygulamalarını yerel olarak çalıştırmak için (Apache / Passenger veya benzerlerini kullanmak yerine ) Foreman'ı ( Heroku Araç Kemeri ile yüklenir ) kullanır . Foreman ve Heroku , uygulamanız tarafından hangi komutların çalıştırıldığını bildirmek için kullanır , bu nedenle yerel geliştiriciden Heroku'ya geçiş bu açıdan sorunsuzdur. Her Rails projesinde Foreman ve Heroku kullanıyorum, bu yüzden bu kolaylık harika. Ama olay şu ki .. Foreman , dotenv aracılığıyla depolanan ortam değişkenlerini yükler, ancak ne yazık ki dotenv, esasen dosyayı çiftler için ayrıştırırrails serverProcfile/.envkey=value; bu çiftler tam orada değişkenler haline gelmezler, bu nedenle önceden ayarlanmış değişkenlere (şeyleri KURU tutmak için) başvuramazsınız veya orada "Ruby" yapamazsınız (yukarıda koşullarla belirtildiği gibi), bunu yapabilirsiniz yapmak /config/app_environment_variables.rb. Örneğin, kuru tutma açısından bazen şöyle şeyler yapıyorum:

ENV['SUPPORT_EMAIL']='Company Support <support@company.com>'
ENV['MAILER_DEFAULT_FROM'] = ENV['SUPPORT_EMAIL']
ENV['MAILER_DEFAULT_TO']   = ENV['SUPPORT_EMAIL']

Bu nedenle, uygulamalarımı yerel olarak çalıştırmak için Foreman kullanıyorum, ancak .envdosyasını ortam değişkenlerini yüklemek için kullanmıyorum ; daha ziyade Foreman'ı /config/app_environment_variables.rbyukarıda açıklanan yaklaşımla birlikte kullanıyorum .


3
Hassas ayarların (API anahtarları vb.) Temiz metin yerine bir anahtar deposunda yeterince korunduğundan ve Git deposu ile paketlenmediğinden emin olmak istediğim için bu çözümü seviyorum. Teşekkürler.
Rori Stumpf

10

Sorumda bunu yapmaya çalıştığım yol aslında işe yarıyor!

# environment/development.rb

ENV['admin_password'] = "secret" 

Sadece sunucuyu yeniden başlatmam gerekti. reload!Raylar konsolunda çalıştırmanın yeterli olacağını düşündüm ancak web sunucusunu da yeniden başlatmam gerekti.

Kendi cevabımı seçiyorum çünkü buranın ENV değişkenlerini koymak ve ayarlamak için daha iyi bir yer olduğunu düşünüyorum.


Neden işe yaramadığını öğrendiğine sevindim! Kişisel olarak Rails ortamını kaydetmeyi config/application.rbve config/environments/*.rbkurmayı ve uygulama ortamımı kurmak için diğer yöntemleri kullanmayı seviyorum , ancak bu kesinlikle bunun tek yol olduğu (hatta "doğru" yol olduğu anlamına gelmiyor :)
Michelle Tilley

Üretim ve geliştirme arasında her şeyi farklı ayarlamaya çalıştığım için biraz atıldım. Ama şimdi sana tamamen katılıyorum! Yalnızca orijinal sorumu yanıtlamakla kalmayıp aynı zamanda rayların uygulama yapısını daha iyi anlamama yardımcı olduğunuz için teşekkürler!
Lan

8

Buradaki çözümlerin yanı sıra, belirli geliştirme sunucularını kullanıyorsanız daha temiz alternatifler var.

Heroku'nun Foreman'ı ile bir .envdosyada proje başına ortam değişkenleri oluşturabilirsiniz :

ADMIN_PASSOWRD="secret"

Pow ile bir .powenvdosya kullanabilirsiniz :

export ADMIN_PASSOWRD="secret"

2

Bence en iyi yol, onları bir yml dosyasında saklamak ve ardından bu komutu kullanarak bu dosyayı intializer dosyasında yüklemek.

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

ortamla ilgili yapılandırma değişkenlerine kolayca erişebilirsiniz.

Yml dosyanızın anahtar değeri yapınız:

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

production:
  app_key: 'xyz'
  app_secret: 'ghq'

1

Sistem ortamı ve rayların ortamı farklı şeylerdir. ENVhadi rayların ortamıyla çalışalım, ancak yapmak istediğiniz şey sistemin ortamını çalışma zamanında değiştirmekse, komutu sadece geri işaretleriyle çevreleyebilirsiniz.

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

1
Sadece exportboşluklardan şikayet edecek bir not ; tryexport admin_password="secret"
Michelle Tilley

Bu (çok önemli) detayı unuttum. Cevabımı düzelttim, teşekkürler!
goncalossilva

Ters vuruşlar bir alt kabuk oluşturduğundan ve alt kabukta ayarladığınız değişkenler üst öğenin ortamını etkileyemediğinden bu işe yaramaz.
AndrewF

Hayır, işe yarıyor. Cevap, açıkça belirtildiği gibi, ebeveynin çevresini hedef almıyor. Bunun nasıl yapılacağını öğreten mükemmel cevaplar var.
goncalossilva

1

Özel .envdosya yükleme komut dosyası: Aşağıdaki satırları satır /config/environment.rbve requiresatır arasına ekleyin 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

Ve config/local_environment.env(isteyeceksin .gitignore) şöyle görünecek:

# This is ignored comment
DATABASE_URL=mysql2://user:psw@0.0.0:3307/database
RACK_ENV=development

(@ User664833 çözümüne göre)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.