Jak rozwiązać błąd "Brak' tajnej bazy kluczy 'dla środowiska' produkcyjnego '" (Rails 4.1)

Stworzyłem aplikację Rails, używając Rails 4.1, od zera i stoję przed dziwnym problemem, którego nie jestem w stanie rozwiązać.

Za każdym razem, gdy próbuję wdrożyć moją aplikację na Heroku, dostaję błąd 500:

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

Plik secret.yml zawiera następującą konfigurację:

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

W Heroku skonfigurowałem zmienną środowiskową "SECRET_KEY_BASE" z wynikiem polecenia rake secret. Jeśli uruchamiam heroku config, widzę zmienną o prawidłowej nazwie i wartość.

Dlaczego wciąż dostaję ten błąd?

Author: the Tin Man, 2014-04-20

15 answers

Miałem ten sam problem i rozwiązałem go, tworząc zmienną środowiskową, która będzie ładowana za każdym razem, gdy zalogowałem się na serwer produkcyjny, i zrobiłem mini-przewodnik z krokami, aby ją skonfigurować:

Używałem Rails 4.1 z Unicorn v4.8. 2 i kiedy próbowałem wdrożyć moją aplikację, nie uruchomiła się poprawnie i w pliku unicorn.log znalazłem komunikat o błędzie:

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

Po kilku badaniach dowiedziałem się, że Rails 4.1 zmienił sposób zarządzania secret_key, więc jeśli czytasz w pliku secrets.yml znajdującym się pod exampleRailsProject/config/secrets.yml znajdziesz coś takiego:

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

Oznacza to, że Rails zaleca użycie zmiennej środowiskowej dla secret_key_base w serwerze produkcyjnym. Aby rozwiązać ten błąd, należy wykonać następujące kroki, aby utworzyć zmienną środowiskową dla Linuksa (w moim przypadku Ubuntu) na serwerze produkcyjnym: {]}

  1. W terminalu twojego serwera produkcyjnego wykonaj:

    $ RAILS_ENV=production rake secret
    

    Zwraca duży ciąg znaków z literami i cyframi. Skopiuj to, co będziemy odnosić się do tego kodu jako GENERATED_CODE.

  2. Zaloguj się na swój Serwer

    • Jeśli zalogujesz się jako użytkownik root, znajdź ten plik i edytuj go:

      $ vi /etc/profile
      

      Przejdź do dołu pliku używając Shift+G (wielka litera "G") w vi.

      Zapisz zmienną środowiskową za pomocą GENERATED_CODE, naciskając i , aby wstawić w vi. upewnij się, że na końcu pliku znajduje się nowa linia:

      $ export SECRET_KEY_BASE=GENERATED_CODE
      

      Zapisz zmiany i zamknij plik używając Esc , a następnie" :x " i wprowadź, aby zapisać i zakończyć w vi.

    • Ale jeśli logujesz się jako zwykły użytkownik, nazwijmy go "example_user " dla tego GISTA, będziesz musiał znaleźć jeden z tych innych plików:

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

      Te pliki są w kolejności ważności, co oznacza, że jeśli masz pierwszy plik, nie musisz edytować innych. Jeśli znalazłeś te dwa pliki w swoim katalogu ~/.bash_profile i ~/.profile będziesz musiał napisać tylko w pierwszym ~/.bash_profile, ponieważ Linux odczyta tylko ten jeden, a drugi zostanie zignorowany.

      Następnie przechodzimy do dołu pliku używając Shift+G ponownie i zapisz zmienną środowiskową za pomocą naszego GENERATED_CODE używając i ponownie, i upewnij się, że dodasz nową linię na końcu pliku:

      $ export SECRET_KEY_BASE=GENERATED_CODE
      

      Po zapisaniu kodu Zapisz zmiany i zamknij plik używając Esc ponownie i ":x" oraz wpisz aby zapisać i wyjście.

  3. Możesz sprawdzić, czy nasza zmienna środowiskowa jest poprawnie ustawiona w Linuksie za pomocą tego polecenia:

    $ printenv | grep SECRET_KEY_BASE
    

    Lub z:

    $ echo $SECRET_KEY_BASE
    

    Kiedy wykonasz to polecenie, jeśli wszystko poszło dobrze, pokaże ci GENERATED_CODE z wcześniej. Na koniec po wykonaniu całej konfiguracji powinieneś być w stanie wdrożyć bez problemów aplikację Rails z jednorożcem lub innym narzędziem.

Po zamknięciu powłoki i ponownym zalogowaniu się do serwer produkcyjny ta zmienna środowiskowa będzie ustawiona i gotowa do użycia.

I to wszystko! Mam nadzieję, że ten mini-przewodnik pomoże Ci rozwiązać ten błąd.

Disclaimer: Nie jestem guru Linuksa ani Railsa, więc jeśli znajdziesz coś nie tak lub jakikolwiek błąd, chętnie to naprawię.

 209
Author: Demi Magus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-22 20:34:03

Zakładam, że nie masz swojego secrets.yml sprawdzonego w kontroli źródła (tj. jest w pliku .gitignore). Nawet jeśli nie jest to twoja sytuacja, wiele innych osób oglądających to pytanie zrobiło tak, ponieważ mają swój kod ujawniony na Githubie i nie chcą, aby ich tajny klucz krążył wokół.

Jeśli nie jest pod kontrolą źródła, Heroku o tym nie wie. Tak więc Rails szuka Rails.application.secrets.secret_key_base i nie został ustawiony, ponieważ rails ustawia go sprawdzając plik secrets.yml, który nie istnieć. Prostym obejściem jest przejście do pliku config/environments/production.rb i dodanie następującej linii:
Rails.application.configure do
    ...
    config.secret_key_base = ENV["SECRET_KEY_BASE"]
    ...
end

Mówi To aplikacji, aby ustawiła tajny klucz przy użyciu zmiennej środowiskowej zamiast szukać go w secrets.yml. Zaoszczędziłoby mi to dużo czasu, gdybym wiedział o tym z góry.

 88
Author: Erik Trautman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-24 04:58:37

Dodać config/secrets.yml do kontroli wersji i wdrożyć ponownie. Może być konieczne usunięcie linii z .gitignore, aby można było zatwierdzić plik.

Miałem dokładnie ten sam problem i okazało się, że boilerplate .gitignore Github stworzony dla mojej aplikacji Rails zawiera config/secrets.yml.

 54
Author: danielricecodes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-05 14:49:53

To mi pomogło.

SSH do serwera produkcyjnego i cd do bieżącego katalogu, uruchom bundle exec rake secret lub rake secret, otrzymasz długi łańcuch jako wyjście, skopiuj ten łańcuch.

A teraz uciekaj sudo nano /etc/environment.

Wklej na dole pliku

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

Gdzie rake secret jest właśnie skopiowanym łańcuchem, wklej ten skopiowany łańcuch w miejsce rake secret.

Uruchom ponownie serwer i przetestuj przez uruchomienie echo $SECRET_KEY_BASE.

 13
Author: sumitsv21,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-19 20:34:48

Podczas gdy możesz używać inicjalizatorów, tak jak inne odpowiedzi, konwencjonalnym sposobem Rails 4.1+ jest użycie config/secrets.yml. Powodem, dla którego zespół Rails wprowadził To rozwiązanie jest poza zakresem tej odpowiedzi, ale TL; DR jest to, że secret_token.rb łączy konfigurację i kod, a także stanowi zagrożenie bezpieczeństwa, ponieważ token jest sprawdzany w historii kontroli źródeł i jedynym systemem, który musi znać tajny token produkcji, jest Infrastruktura produkcyjna.

Powinieneś dodać ten plik do .gitignore podobnie jak nie dodałbyś config/database.yml do kontroli źródła.

Nawiązując do własnego kodu Heroku do konfiguracji config/database.yml z DATABASE_URLw ich Buildpack for Ruby , skończyłem rozwidlając ich repo i zmodyfikowałem go, aby utworzyć config/secrets.yml ze zmiennej środowiskowej SECRETS_KEY_BASE.

Ponieważ ta funkcja została wprowadzona w Rails 4.1, uznałem za stosowne edytować ./lib/language_pack/rails41.rb i dodać tę funkcjonalność.

Poniżej znajduje się fragment ze zmodyfikowanego buildpacka I stworzony w mojej firmie:

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

Możesz oczywiście rozszerzyć ten kod, aby dodać inne tajemnice (np. klucze API innych firm itp.) do odczytu ze zmiennej środowiskowej:

...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
W ten sposób możesz uzyskać dostęp do tego sekretu w bardzo standardowy sposób:]}
Rails.application.secrets.third_party_api_key

Przed ponownym uruchomieniem aplikacji należy najpierw ustawić zmienną środowiskową: Ustawienie SECRET_KEY_BASE w Panelu Heroku

Następnie dodaj swój zmodyfikowany buildpack (lub jesteś bardziej niż mile widziany, aby link do mojego) do swojej aplikacji Heroku (zobacz Heroku dokumentacja) i przesuń swoją aplikację.

Buildpack automatycznie utworzy config/secrets.yml ze zmiennej środowiskowej jako część procesu budowania dyno za każdym razem, gdy git push trafisz do Heroku.

EDIT: własna dokumentacja Heroku sugeruje utworzenie config/secrets.yml do odczytu ze zmiennej środowiskowej, ale oznacza to, że powinieneś sprawdzić ten plik w kontroli źródła. W moim przypadku nie działa to dobrze, ponieważ mam zakodowane sekrety rozwoju i testowania środowiska, których wolałbym nie sprawdzać.

 3
Author: stackunderflow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-25 23:25:13

W przypadku rails6 miałem ten sam problem, ponieważ brakowało mi następujących plików, po dodaniu ich problem rozwiązany:

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

Upewnij się, że masz te pliki.!!!

 2
Author: Tushar H,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-16 05:07:06

Możesz wyeksportować tajne klucze do zmiennych środowiskowych na ~/.bashrc lub ~/.bash_profile twojego serwera:

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

A następnie możesz podać swoje .bashrc lub .bash_profile:

source ~/.bashrc 
source ~/.bash_profile

Nigdy nie zdradzaj swoich sekretów.yml

 1
Author: alessandrocb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-19 20:35:20

W moim przypadku problem polegał na tym, że config/master.key nie było w kontroli wersji, a ja stworzyłem projekt na innym komputerze.

Domyślne .gitignore, który tworzy Rails, wyklucza ten plik. Ponieważ nie można go wdrożyć bez posiadania tego pliku, musi on być pod kontrolą wersji, aby móc go wdrożyć z komputera dowolnego członka zespołu.

Rozwiązanie: usuń linię config/master.key z .gitignore, Zatwierdź Plik z komputera, na którym został utworzony projekt, a teraz możesz git pull na drugim komputerze i wdrożyć z niego.

Ludzie mówią, aby nie przenosić niektórych z tych plików do kontroli wersji, bez oferowania alternatywnego rozwiązania. Dopóki nie pracujesz nad projektem open source, nie widzę powodu, aby nie zatwierdzać wszystkiego, co jest wymagane do uruchomienia projektu, w tym poświadczeń.

 1
Author: Andrew Koster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-20 18:25:03

What I did : Na moim serwerze produkcyjnym tworzę plik config (confthin.yml) dla Thin (używam go) i dodaj następującą informację:

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

Następnie uruchamiam aplikację z

thin start -C /whereeveristhefieonprod/configthin.yml

Działa jak czar, a następnie nie trzeba mieć tajnego klucza w kontroli wersji

Mam nadzieję, że to pomoże, ale jestem pewien, że to samo można zrobić z jednorożcem i innymi.
 0
Author: Geraud Puechaldou,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-13 15:25:41

Mam łatkę, której użyłem w aplikacji Rails 4.1, aby pozwolić mi kontynuować korzystanie z generatora kluczy starszych (a tym samym kompatybilność sesji wstecznej z Rails 3), pozwalając secret_key_base być puste.

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

Od tego czasu sformatowałem łatkę wysłałem ją do Rails jako Pull Request

 -1
Author: BF4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-28 01:57:51

Utworzyłem config/initializers/secret_key.rb plik i napisałem tylko następującą linijkę kodu:

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

Ale myślę, że rozwiązanie dodane przez @ Erik Trautman jest bardziej eleganckie;)

Edytuj: No i w końcu znalazłem taką radę na Heroku: https://devcenter.heroku.com/changelog-items/426 :)

Smacznego!
 -1
Author: fadehelix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:56

This is works good https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 dla użytkownika root należy edytować

$ /etc/profile

Ale jeśli nie root należy umieścić kod generujący w następujący

$ ~/.bash_profile

$ ~/.bash_login

$ ~/.profile
 -1
Author: bung_firman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 07:58:49

Na Nginx / Passenger / Ruby (2.4)/Rails (5.1.1) nic innego nie działało poza:

passenger_env_var in /etc/nginx/sites-available/default in the server block.

Źródło: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var

 -1
Author: Kasperi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-17 07:25:19

Demi Magus odpowiedź działała dla mnie do Rails 5.

W naszej ofercie znajdują się również akcesoria do wózków widłowych, wózków widłowych i wózków widłowych.]}
export SECRET_KEY_BASE=GENERATED_CODE
W związku z tym, że nie jesteśmy w stanie się z nami skontaktować, prosimy o kontakt z naszym biurem obsługi klienta.

Źródło: https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache

 -1
Author: Florent L.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-25 11:51:09

Miałem ten sam problem po użyciu .plik gitignore z https://github.com/github/gitignore/blob/master/Rails.gitignore

Wszystko poszło dobrze po tym, jak skomentowałem następujące linijki w .plik gitignore.

config/initializers/secret_token.rb
config/secrets.yml
 -3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-27 17:55:59