Bagaimana mengatasi kesalahan “Missing` secret_key_base` untuk lingkungan 'produksi' ”(Rails 4.1)

169

Saya membuat aplikasi Rails, menggunakan Rails 4.1, dari awal dan saya menghadapi masalah aneh yang tidak dapat saya pecahkan.

Setiap kali saya mencoba untuk menyebarkan aplikasi saya di Heroku saya mendapatkan kesalahan 500:

Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`

The secret.ymlfile berisi konfigurasi sebagai berikut:

secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Di Heroku saya mengonfigurasi SECRET_KEY_BASEvariabel lingkungan " " dengan hasil dari rake secretperintah. Jika saya meluncurkan heroku config, saya bisa melihat variabel dengan nama dan nilai yang benar.

Mengapa saya masih mendapatkan kesalahan ini?

Paolo Laurenti
sumber
1
Saya memiliki masalah yang sama persis dan ingin tahu mengapa ini terjadi juga. Jika saya mengetahui alasannya, saya akan mengirim kembali dengan solusi saya.
danielricecodes
Apakah file konfigurasi Anda dipanggil secret.ymlatau secrets.yml?
James
2
Saya mengkonfigurasi lagi file .gitignore dengan yang dihasilkan oleh rails dan sekarang semuanya berfungsi dengan baik
Paolo Laurenti
Kami juga memiliki masalah ini ketika kami meningkatkan ke Rails 4. Dalam kasus kami, itu karena kami memiliki nama lingkungan kustom, dan itu tidak tercermin dalam secrets.yml. Saya hanya perlu menambahkan baris ke file dengan nama yang tidak standar, komit, dan gunakan kembali.
whognu
Untuk pembaca masa depan: jawaban ini mungkin yang termudah dan paling akurat: stackoverflow.com/a/26541742/4880924
BKSpurgeon

Jawaban:

208

Saya memiliki masalah yang sama dan menyelesaikannya dengan membuat variabel lingkungan untuk dimuat setiap kali saya masuk ke server produksi, dan membuat mini-panduan langkah-langkah untuk mengkonfigurasinya:

Saya menggunakan Rails 4.1 dengan Unicorn v4.8.2 dan ketika saya mencoba untuk menyebarkan aplikasi saya itu tidak mulai dengan benar dan dalam unicorn.logfile saya menemukan pesan kesalahan ini:

app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)

Setelah beberapa penelitian saya menemukan bahwa Rails 4.1 mengubah cara mengelola secret_key, jadi jika Anda membaca secrets.ymlfile yang terletak di exampleRailsProject/config/secrets.ymlAnda akan menemukan sesuatu seperti ini:

# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

Ini berarti bahwa Rails merekomendasikan Anda untuk menggunakan variabel lingkungan untuk secret_key_basedi server produksi Anda. Untuk mengatasi kesalahan ini, Anda harus mengikuti langkah-langkah ini untuk membuat variabel lingkungan untuk Linux (dalam kasus saya Ubuntu) di server produksi Anda:

  1. Di terminal server produksi Anda jalankan:

    $ RAILS_ENV=production rake secret

    Ini mengembalikan string besar dengan huruf dan angka. Salin itu, yang akan kita sebut kode itu sebagai GENERATED_CODE.

  2. Login ke server Anda

    • Jika Anda masuk sebagai pengguna root, cari file ini dan edit:

      $ vi /etc/profile

      Buka bagian bawah file menggunakan Shift+ G(huruf besar "G") di vi.

      Tulis variabel lingkungan Anda dengan GENERATED_CODE, tekan iuntuk menyisipkan di vi. Pastikan berada di baris baru di akhir file:

      $ export SECRET_KEY_BASE=GENERATED_CODE

      Simpan perubahan dan tutup file menggunakan Esclalu " :x" dan Enteruntuk menyimpan dan keluar di vi.

    • Tetapi jika Anda masuk sebagai pengguna normal, sebut saja " example_user" untuk inti ini, Anda perlu menemukan salah satu dari file-file ini:

      $ vi ~/.bash_profile
      $ vi ~/.bash_login
      $ vi ~/.profile
      

      File-file ini dalam urutan kepentingan, yang berarti bahwa jika Anda memiliki file pertama, maka Anda tidak perlu mengedit yang lain. Jika Anda menemukan dua file ini di direktori Anda ~/.bash_profiledan ~/.profileAnda hanya perlu menulis di yang pertama ~/.bash_profile, karena Linux hanya akan membaca yang ini dan yang lainnya akan diabaikan.

      Kemudian kita pergi ke bagian bawah file menggunakan Shift+ Glagi dan menulis variabel lingkungan dengan GENERATED_CODEmenggunakan kita ilagi, dan pastikan menambahkan baris baru di akhir file:

      $ export SECRET_KEY_BASE=GENERATED_CODE

      Setelah menulis kode, simpan perubahan dan tutup file menggunakan Esclagi dan " :x" dan Enteruntuk menyimpan dan keluar.

  3. Anda dapat memverifikasi bahwa variabel lingkungan kami diatur dengan benar di Linux dengan perintah ini:

    $ printenv | grep SECRET_KEY_BASE

    atau dengan:

    $ echo $SECRET_KEY_BASE

    Ketika Anda menjalankan perintah ini, jika semuanya berjalan baik, itu akan menunjukkan kepada Anda GENERATED_CODEdari sebelumnya. Akhirnya dengan semua konfigurasi yang dilakukan Anda harus dapat menggunakan tanpa masalah aplikasi Rails Anda dengan Unicorn atau alat lainnya.

Ketika Anda menutup shell dan login lagi ke server produksi, Anda akan memiliki set variabel lingkungan ini dan siap untuk menggunakannya.

Dan itu dia! Saya harap mini-guide ini membantu Anda mengatasi kesalahan ini.

Penafian: Saya bukan guru Linux atau Rails, jadi jika Anda menemukan sesuatu yang salah atau kesalahan, saya akan dengan senang hati memperbaikinya.

Demi Magus
sumber
11
Tampaknya, Rails tidak melihat variabel lingkungan SECRET_KEY_BASE. printenv menunjukkannya, rel c produksi juga menampilkannya, jika saya memeriksa ENV. Tapi, saya tidak punya efek, ketika saya me-restart Unicorn. Satu-satunya cara, yang berfungsi sekarang, adalah menempelkannya langsung ke secrets.yml
AntonAL
1
Ini berhasil untuk saya. Terima kasih atas penjelasan lengkapnya. Saya baru belajar bahwa ada permata yang ada untuk mengelola variabel lingkungan aplikasi. 'Dotenv' adalah satu dan 'mandor' untuk heroku. Sementara itu adalah pendidikan untuk memperbaiki kesalahan secara manual dengan cara ini, mungkin menggunakan salah satu permata itu akan memperlancar proses?
Nick Res
Saya senang bahwa jawaban saya sangat membantu, terima kasih untuk opsi permata @ ninja08, mereka secara definitif membuat proses lebih mudah, terutama bagi mereka yang menggunakan capistrano atau alat tambahan lainnya untuk mengelola server :)
Demi Magus
Mengikuti instruksi bagus Demi Magus, saya melakukan sesuatu seperti ini: cd / var / www / rails; rvm gunakan ext-rbx-2.5.2@rails; SKB_FILE = / var / www / .secret_key_base; echo "export SECRET_KEY_BASE = $ (RAILS_ENV = rahasia rake produksi)"> $ SKB_FILE; . $ SKB_FILE; echo ". $ SKB_FILE" | tee -a ~ / .bashrc ~ / .bash_profile; chmod o-rwx $ SKB_FILE;
David Winiecki
Jawaban bagus!! Saya tidak tahu mengapa ini tidak diselesaikan untuk saya, saya membuat pertanyaan stackoverflow.com/questions/33117318/…
Adriano Resende
84

Saya akan berasumsi bahwa Anda tidak memiliki Anda secrets.ymldiperiksa ke dalam kontrol sumber (mis. Itu ada di .gitignorefile). Bahkan jika ini bukan situasi Anda, itulah yang dilakukan banyak orang yang melihat pertanyaan ini karena kode mereka diekspos di Github dan tidak ingin kunci rahasia mereka mengambang.

Jika tidak ada dalam kontrol sumber, Heroku tidak tahu tentang itu. Jadi Rails sedang mencari Rails.application.secrets.secret_key_basedan belum ditetapkan karena Rails menetapkannya dengan memeriksa secrets.ymlfile yang tidak ada. Solusi sederhana adalah masuk ke config/environments/production.rbfile Anda dan tambahkan baris berikut:

Rails.application.configure do
    ...
    config.secret_key_base = ENV["SECRET_KEY_BASE"]
    ...
end

Ini memberi tahu aplikasi Anda untuk mengatur kunci rahasia menggunakan variabel lingkungan alih-alih mencarinya secrets.yml. Itu akan menyelamatkan saya banyak waktu untuk mengetahui hal ini di muka.

Erik Trautman
sumber
15
Ini jawaban terbaik. Figarodan heroku_secretstidak melakukan apa pun kecuali Rails tahu bahwa itu SECRET_KEY_BASEtinggal di ENV. Saya telah berjuang dengan pemikiran ini bahwa jika konfigurasi ada pada Heroku, Rails akan mengambilnya hanya karena itu ada, tetapi sekarang tampaknya sangat menyolok bahwa Rails perlu tahu di mana mencarinya. Saya bertanya-tanya bagaimana saya dapat memiliki kode pada Github tanpa harus khawatir tentang hal basis kunci rahasia; sekarang saya tahu.
flanger001
1
Setuju, saya pikir secrets.yml berlebihan dengan permata besar seperti Figaro.
Joe
2
Sepertinya opsi terbaik jika Anda menggunakan github dan heroku untuk proyek Anda.
flexus
1
Apa yang salah dengan melakukan rahasia Anda production: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>. Bukankah itu juga berarti kunci rahasia yang sebenarnya tidak terbuka. Apakah ada risiko untuk mengekspos dev dan menguji kunci dalam rahasia yang dilakukan.yml jika itu semua hanya data unggulan dan uji?
Jay Killeen
Ini bekerja bahkan di Rails 6.0.2, ketika tidak ada secrets.yml lagi.
Ken Tsoi
54

Tambahkan config/secrets.ymlke kontrol versi dan gunakan lagi. Anda mungkin perlu menghapus satu baris dari .gitignoresehingga Anda dapat mengkomit file.

Saya memiliki masalah yang sama persis ini dan ternyata .gitignoreGithub boilerplate yang dibuat untuk aplikasi Rails saya disertakan config/secrets.yml.

kode danielric
sumber
140
config / secrets.yml harus PERNAH berada di repo Anda dapat do.yml.sample dan mengisinya dengan data palsu tapi untuk keamanan, tidak pernah melakukan .yml di repo
user3379926
9
@ user3379926, dalam konteks aplikasi Rails di Heroku, Anda tidak bisa memilih file mana yang termasuk dalam kontrol versi dan mana yang tidak. Rails 4.1 mengharapkan konfigurasi rahasia ada jika tidak aplikasi tidak akan berjalan. Jika Anda memiliki cara untuk menyelesaikan masalah yang ditimbulkan dalam Pertanyaan di atas tanpa menggunakan file secrets.yml di Git, tolong bantu perbaiki utas ini dengan memberikan saran itu.
danielricecodes
9
@danielricecodes Anda dapat secara manual mengatur nilai dalam penginisialisasi. Sesuatu seperti Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]akan berfungsi dan menghapus kesalahan tanpa menambahkan secrets.ymlke sumber.
joshhepworth
11
@ user3379926: Ketika saya membuat aplikasi Rails baru dengan rails new(menghasilkan, dalam hal ini, Gemfile yang railspermata memiliki versi 4.2.4), file config/secrets.ymldihasilkan. Ini termasuk pregenerated kunci rahasia untuk pengembangan dan uji lingkungan, dan membaca secretkey untuk lingkungan produksi dari variabel lingkungan: secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>. Menurut saya itu sangat aman, dan memang bermanfaat, untuk menjaga secrets.ymlfile ini dalam kontrol versi, asalkan orang tidak pernah benar-benar mendefinisikan kunci rahasia di sana.
Teemu Leisti
2
@jasonleonhard mengapa? jika Anda membaca kunci rahasia dari env vars, apa masalahnya? tidak ada rahasia yang terungkap.
horseyguy
13

Ini berhasil untuk saya.

SSH ke server produksi Anda dan cdke direktori Anda saat ini, jalankan bundle exec rake secretatau rake secret, Anda akan mendapatkan string panjang sebagai output, salin string itu.

Sekarang jalankan sudo nano /etc/environment.

Rekatkan di bagian bawah file

export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'

Di mana rake secretstring yang baru saja Anda salin, tempel string yang disalin di tempat rake secret.

Mulai ulang server dan uji dengan menjalankan echo $SECRET_KEY_BASE.

sumitsv21
sumber
3

Meskipun Anda dapat menggunakan inisialisasi seperti jawaban lain, cara Rails 4.1+ konvensional adalah dengan menggunakan config/secrets.yml. Alasan bagi tim Rails untuk memperkenalkan ini berada di luar cakupan jawaban ini tetapi TL; DR adalah yang secret_token.rbmengonfigurasi konfigurasi dan kode serta menjadi risiko keamanan karena token tersebut diperiksa ke dalam sejarah kendali sumber dan satu-satunya sistem yang perlu tahu token rahasia produksi adalah infrastruktur produksi.

Anda harus menambahkan file ini .gitignoreseperti Anda tidak akan menambahkan config/database.ymlkontrol sumber juga.

Merujuk kode Heroku sendiri untuk pengaturan config/database.ymldari DATABASE_URLdalam Buildpack mereka untuk Ruby , saya akhirnya mengambil repo mereka dan memodifikasinya untuk dibuat config/secrets.ymldari SECRETS_KEY_BASEvariabel lingkungan.

Karena fitur ini diperkenalkan di Rails 4.1, saya merasa pantas untuk mengedit ./lib/language_pack/rails41.rbdan menambahkan fungsi ini.

Berikut ini cuplikan dari buildpack modifikasi yang saya buat di perusahaan saya:

class LanguagePack::Rails41 < LanguagePack::Rails4

  # ...

  def compile
    instrument "rails41.compile" do
      super
      allow_git do
        create_secrets_yml
      end
    end
  end

  # ...

  # writes ERB based secrets.yml for Rails 4.1+
  def create_secrets_yml
    instrument 'ruby.create_secrets_yml' do
      log("create_secrets_yml") do
        return unless File.directory?("config")
        topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
        File.open("config/secrets.yml", "w") do |file|
          file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>

<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
          SECRETS_YML
        end
      end
    end
  end

  # ...

end

Tentu saja Anda dapat memperluas kode ini untuk menambahkan rahasia lain (mis. Kunci API pihak ketiga, dll.) Untuk dibaca dari variabel lingkungan Anda:

...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>

Dengan cara ini, Anda dapat mengakses rahasia ini dengan cara yang sangat standar:

Rails.application.secrets.third_party_api_key

Sebelum mempekerjakan kembali aplikasi Anda, pastikan untuk mengatur variabel lingkungan Anda terlebih dahulu: Mengatur SECRET_KEY_BASE di Dashboard Heroku

Kemudian tambahkan buildpack Anda yang dimodifikasi (atau Anda dipersilakan untuk menautkan ke tambang) ke aplikasi Heroku Anda (lihat dokumentasi Heroku ) dan gunakan kembali aplikasi Anda.

Buildpack akan secara otomatis membuat Anda config/secrets.ymldari variabel lingkungan Anda sebagai bagian dari proses pembangunan dyno setiap kali Anda git pushke Heroku.

EDIT: Dokumentasi Heroku sendiri menyarankan config/secrets.ymluntuk membuat membaca dari variabel lingkungan tetapi ini menyiratkan Anda harus memeriksa file ini ke dalam kontrol sumber. Dalam kasus saya, ini tidak berfungsi dengan baik karena saya memiliki rahasia hardcoded untuk pengembangan dan pengujian lingkungan yang saya lebih suka tidak memeriksa.

stackunderflow
sumber
Sementara solusi hebat, permata .dotenv dan .foreman menyelesaikan masalah ini: "Saya memiliki rahasia yang dikodekan untuk pengembangan dan pengujian lingkungan" - jadi menggunakan permata itu berarti Anda tidak memerlukan buildpack karena Anda dapat menggunakan ENV_VAR dalam file rahasia Anda untuk dev dan Tes juga
rmcsharry
Perhatikan bahwa variabel lingkungan dicatat oleh sebagian besar infrastruktur, yang berarti variabel lingkungan yang tidak dienkripsi akan berada dalam teks biasa di log. Saya tidak menggunakan Heroku untuk aplikasi Rails saya, jadi tidak punya rekomendasi untuk itu, tetapi dengan AWS kami menarik nilai terenkripsi dari Parameter Store selama membangun dari dalam wadah build dan tidak mengenkripsi mereka untuk mengisi jenis aset aman ini.
Daniel Nalbach
1

Anda dapat mengekspor kunci rahasia ke sebagai variabel lingkungan di ~/.bashrcatau ~/.bash_profiledari server Anda:

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

Dan kemudian, Anda dapat mengambil sumber .bashrcatau .bash_profile:

source ~/.bashrc 
source ~/.bash_profile

Jangan pernah melakukan rahasia Anda .yml

alessandrocb
sumber
1

Dalam kasus saya, masalahnya adalah yang config/master.keytidak ada dalam kontrol versi, dan saya telah membuat proyek di komputer yang berbeda.

.Gitignore default yang dibuat Rails mengecualikan file ini. Karena tidak mungkin untuk menyebarkan tanpa memiliki file ini, itu perlu di kontrol versi, agar dapat digunakan dari komputer anggota tim mana pun.

Solusi: hapus config/master.keybaris dari .gitignore, komit file dari komputer tempat proyek itu dibuat, dan sekarang Anda dapat git pulldi komputer lain dan menyebarkan dari itu.

Orang-orang mengatakan untuk tidak melakukan beberapa file ini ke kontrol versi, tanpa menawarkan solusi alternatif. Selama Anda tidak mengerjakan proyek sumber terbuka, saya tidak melihat alasan untuk tidak melakukan semua yang diperlukan untuk menjalankan proyek, termasuk kredensial.

Andrew Koster
sumber
Jangan pernah komit file kunci master Anda ke git. Ini adalah kerentanan keamanan raksasa untuk aplikasi Anda. Untuk open source itu sulit, tetapi membuat brankas kata sandi dengan manajer kata sandi pilihan Anda adalah pilihan yang lebih baik.
wsizoo
Mengapa ini merupakan kerentanan keamanan, jika repo bersifat pribadi? Jika orang yang tidak berwenang memiliki akses ke repo pribadi saya, maka saya memiliki masalah lebih besar dari sekadar bocornya kunci API. Tidak semua proyek open source.
Andrew Koster
Saya merasa semua orang mengulang ini karena mereka melihatnya dalam tutorial untuk proyek open-source.
Andrew Koster
Semua ini sangat membingungkan karena ada begitu banyak dokumentasi usang tentang secrets.ymlfile lama , yang telah usang untuk beberapa versi Rails sebelumnya. Pertanyaan Stack Overflow ini sendiri memiliki banyak jawaban, dan mereka hampir semuanya menggunakan API kuno ini.
Andrew Koster
1

Untuk rails6, saya menghadapi masalah yang sama, karena saya kehilangan file berikut, setelah saya menambahkannya, masalah terselesaikan:

1. config/master.key
2. config/credentials.yml.enc

Pastikan Anda memiliki file ini. !!!

Tushar H
sumber
0

Apa yang saya lakukan: Di server produksi saya, saya membuat file config (confthin.yml) untuk Thin (saya menggunakannya) dan menambahkan informasi berikut:

environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction

Saya kemudian meluncurkan aplikasi dengan

thin start -C /whereeveristhefieonprod/configthin.yml

Bekerja seperti jimat dan kemudian tidak perlu memiliki kunci rahasia pada kontrol versi

Semoga bisa membantu, tapi saya yakin hal yang sama bisa dilakukan dengan Unicorn dan yang lainnya.

Geraud Puechaldou
sumber
1
dapatkah Anda menjelaskan mengapa / bagaimana ini bekerja? Pertanyaannya adalah untuk heroku. Apakah kurus alternatif, atau apakah itu kompatibel dengan heroku?
ahnbizcad
-1

Saya memiliki tambalan yang telah saya gunakan dalam aplikasi Rails 4.1 untuk membiarkan saya terus menggunakan generator kunci lama (dan karenanya kompatibilitas mundur sesi dengan Rails 3), dengan membiarkan secret_key_base menjadi kosong.

Rails::Application.class_eval do
  # the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
  fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!)
  def validate_secret_key_config! #:nodoc:
    config.secret_token = secrets.secret_token
    if config.secret_token.blank?
      raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
    end 
  end 
end

Saya telah sejak memformat ulang tambalan yang diserahkan ke Rails sebagai Permintaan Tarik

BF4
sumber
-1

Saya telah membuat config/initializers/secret_key.rbfile dan saya hanya menulis baris kode berikut:

Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]

Tapi saya pikir solusi yang diposting oleh @Erik Trautman lebih elegan;)

Sunting: Oh, dan akhirnya saya menemukan saran ini di Heroku: https://devcenter.heroku.com/changelog-items/426 :)

Nikmati!

fadehelix
sumber
-1

ini berfungsi baik https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 untuk pengguna root harus mengedit

$ /etc/profile

tetapi jika Anda bukan root harus memasukkan kode menghasilkan berikut ini

$ ~/.bash_profile

$ ~/.bash_login

$ ~/.profile
bung_firman
sumber
-3

Saya memiliki masalah yang sama setelah saya menggunakan file .gitignore dari https://github.com/github/gitignore/blob/master/Rails.gitignore

Semuanya berjalan dengan baik setelah saya mengomentari baris berikut dalam file .gitignore.

config/initializers/secret_token.rb
config/secrets.yml

sumber
1
Seperti yang diulang di mana-mana, melakukan secrets.yml atau secret_token.rb untuk git TIDAK dianjurkan.
cofiem