Я создал приложение rails (rails 4.1) с нуля, и у меня возникла странная проблема, которую я не могу решить.
Каждый раз, когда я пытаюсь развернуть свое приложение на Heroku, я получаю сообщение об ошибке 500:
Отсутствует
secret_key_base
для среды "production", установите это значение вconfig/secrets.yml
Файл secret.yml содержит следующую конфигурацию:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
В Heroku я настроил переменную окружения "SECRET_KEY_BASE" с результатом команды "rake secret". Если я запустил "конфигурацию героя", я могу увидеть переменную с правильным именем и значением.
Почему я все еще получаю эту ошибку?
Спасибо большое
У меня была такая же проблема, и я решил ее, создав переменную среды, которая будет загружаться каждый раз, когда я вошел в систему на рабочий сервер, и сделал мини-руководство по его настройкам:
https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
Я использовал Rails 4.1 с Unicorn v4.8.2, когда я пытался развернуть свое приложение, он не запускался должным образом, и в файле unicorn.log я нашел это сообщение об ошибке:
app error: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml` (RuntimeError)
После некоторых исследований я узнал, что Rails 4.1 изменил способ управления secret_key, поэтому, если вы читаете файл secrets.yml, расположенный в exampleRailsProject/config/secrets.yml
, вы найдете что-то вроде этого:
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Это означает, что Rails рекомендует использовать переменную среды для secret_key_base
на вашем рабочем сервере, чтобы решить эту ошибку, вы должны следовать этим шагам, чтобы создать переменную среды для Linux (в моем случае Ubuntu) в вашем сервер производства:
В терминале вашего производственного сервера выполните следующую команду:
$ RAILS_ENV=production rake secret
Это возвращает большую строку с буквами и цифрами, скопируйте ее (мы будем ссылаться на этот код как GENERATED_CODE).
Войдите на свой сервер
Если вы входите в систему как пользователь root, найдите этот файл и отредактируйте его:
$ vi /etc/profile
Перейти к нижней части файла ( "SHIFT + G" для капитала G в VI)
Напишите переменную среды с GENERATED_CODE (нажмите клавишу "i" для записи в VI), убедитесь, что она находится в новой строке в конце файла:
$ export SECRET_KEY_BASE=GENERATED_CODE
Сохраните изменения и закройте файл (мы нажимаем клавишу "ESC", а затем записываем клавиши ": x" и "ENTER" для сохранения и выхода в VI).
Но если вы входите в систему как обычный пользователь, давайте назовем его "example_user" для этого gist, вам нужно будет найти один из этих других файлов:
$ vi ~/.bash_profile
$ vi ~/.bash_login
$ vi ~/.profile
Эти файлы в порядке важности, это означает, что если у вас есть первый файл, вам не нужно будет писать в других. Поэтому, если вы нашли эти 2 файла в своем каталоге ~/.bash_profile
и ~/.profile
, вам нужно будет записать только первый ~/.bash_profile
, потому что Linux будет читать только этот, а другой будет проигнорирован.
Затем мы переходим к нижней части файла ( "SHIFT + G" для капитала G в VI).
И мы напишем нашу переменную среды с нашим GENERATED_CODE (нажмите "i" для записи в VI), обязательно в новой строке в конце файла:
$ export SECRET_KEY_BASE=GENERATED_CODE
Записав код, сохраните изменения и закройте файл (мы нажимаем клавишу "ESC", а затем записываем клавиши ": x" и "ENTER" для сохранения и выхода в VI).
Вы можете проверить, что наша переменная среды правильно установлена в Linux с помощью этой команды:
$ printenv | grep SECRET_KEY_BASE
или с помощью:
$ echo $SECRET_KEY_BASE
Когда вы выполните эту команду, если все будет хорошо, она покажет вам GENERATED_CODE. Наконец, при выполнении всей конфигурации вы сможете без проблем развертывать приложение Rails с Unicorn или другим.
Когда вы закроете свой терминал и снова войдете на рабочий сервер, у вас будет установлен этот набор переменных среды и готов к его использованию.
И вот оно! Я надеюсь, что этот мини-справочник поможет вам решить эту ошибку.
Отказ от ответственности: я не являюсь гуру Linux или Rails, поэтому, если вы найдете что-то неправильно или какую-либо ошибку, я буду рад его исправить!
Я предполагаю, что ваш secrets.yml
не установлен в исходном элементе управления (т.е. в файле .gitignore
). Даже если это не ваша ситуация, это то, что многие другие люди рассматривают этот вопрос, потому что они имеют свой код, выставленный на Github, и не хотят, чтобы их секретный ключ плавал вокруг.
Если он не находится в исходном управлении, Героку об этом не знает. Поэтому Rails ищет Rails.application.secrets.secret_key_base
, и он не был установлен, потому что Rails устанавливает его, проверяя файл secrets.yml
, который не существует. Простым решением является переход в ваш файл config/environments/production.rb
и добавление следующей строки:
Rails.application.configure do
...
config.secret_key_base = ENV["SECRET_KEY_BASE"]
...
end
Это говорит вашему приложению, чтобы установить секретный ключ, используя переменную окружения, а не искать ее в secrets.yml
. Это бы сэкономило мне много времени, чтобы знать это заранее.
Figaro
и heroku_secrets
ничего не делают, если Rails не знает, что SECRET_KEY_BASE
живет в ENV
. Я боролся с этим мнением, что если бы существовала переменная конфигурации на Heroku, Rails подхватил бы ее только благодаря ее существованию, но теперь кажется очевидным, что Rails нужно знать, где искать. Мне было интересно, как я могу иметь код на Github, не беспокоясь о секретной базе ключей; теперь я знаю.
Добавьте config/secrets.yml
в управление версиями и развертывание снова. Возможно, вам потребуется удалить строку из .gitignore
, чтобы вы могли зафиксировать файл.
У меня была такая же проблема, и только что оказалось, что шаблонный .gitignore
Github, созданный для моего приложения Rails, включал config/secrets.yml
.
config/secrets.yml
безопасен.
Это сработало для меня.
SSH на ваш производственный сервер и cd
в ваш текущий каталог, запустите bundle exec rake secret
или rake secret
, вы получите длинную строку в качестве вывода, скопируйте эту строку.
Теперь запустите sudo nano /etc/environment
.
Вставить в нижней части файла
export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'
Где rake secret
- только что скопированная строка, вставьте эту скопированную строку вместо rake secret
.
Перезагрузите сервер и протестируйте, запустив echo $SECRET_KEY_BASE
.
Хотя вы можете использовать инициализаторы, как и другие ответы, обычным способом Rails 4.1+ является использование config/secrets.yml
. Причина, по которой команда Rails представить это, выходит за рамки этого ответа, но TL; DR - это то, что secret_token.rb
объединяет конфигурацию и код, а также представляет угрозу безопасности, поскольку токен проверяется в истории управления версиями и единственная система который должен знать маркер производства, является производственной инфраструктурой.
Вы должны добавить этот файл в .gitignore
так же, как вы бы не добавляли config/database.yml
в исходный элемент управления.
Ссылка на собственный код Heroku для настройки config/database.yml
от DATABASE_URL
в Buildpack для Ruby, я закончил разблокировать свое репо и изменить его, чтобы создать переменную среды config/secrets.yml
из SECRETS_KEY_BASE
.
Поскольку эта функция была введена в Rails 4.1, я счел нужным отредактировать ./lib/language_pack/rails41.rb
и добавить эту функциональность.
Ниже представлен фрагмент из измененного buildpack, который я создал в моей компании:
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
Вы можете, конечно, расширить этот код, чтобы добавить другие секреты (например, сторонние ключи API и т.д.), которые будут считаться с вашей переменной среды:
...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
Таким образом, вы можете получить доступ к этому секрету стандартным образом:
Rails.application.secrets.third_party_api_key
Перед повторным развертыванием приложения обязательно установите переменную среды:
Затем добавьте модифицированный buildpack (или вы более чем можете подключиться к моему) в свое приложение Heroku (см. документацию Heroku ) и повторное развертывание вашего приложения.
buildpack автоматически создаст ваш config/secrets.yml
из вашей переменной окружения как часть процесса построения динамической системы каждый раз, когда вы git push
до Heroku.
Вы можете экспортировать секретные ключи в качестве переменных среды на ~/.bashrc
или ~/.bash_profile
вашего сервера:
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
И затем вы можете указать свой .bashrc
или .bash_profile
:
source ~/.bashrc
source ~/.bash_profile
Никогда не совершайте свои secrets.yml
Что я сделал: На моем рабочем сервере я создаю файл конфигурации (confthin.yml) для Thin (я использую его) и добавляю следующую информацию:
environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction
Затем я запускаю приложение с помощью
thin start -C /whereeveristhefieonprod/configthin.yml
Работайте как шарм, а затем нет необходимости иметь секретный ключ в управлении версиями
Надеюсь, это может помочь, но я уверен, что то же самое можно было бы сделать с Unicorn и другими.
В Nginx/Passenger/Ruby (2.4)/Rails (5.1.1) ничего не работает, кроме:
passenger_env_var
в /etc/nginx/sites-available/default
в блоке сервера.
Источник: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
это хорошо работает https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 для пользователя root следует отредактировать
$ /etc/profile
но если вы не root должны поместить код генерации в следующий
$ ~/.bash_profile
$ ~/.bash_login
$ ~/.profile
Я создал файл config/initializers/secret_key.rb
, и я написал только следующую строку кода:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
Но я думаю, что решение, отправленное @Erik Trautman, более изящно;)
Изменить: О, и, наконец, я нашел этот совет по Heroku: https://devcenter.heroku.com/changelog-items/426:)
Наслаждайтесь!
У меня есть патч, который я использовал в приложении Rails 4.1, чтобы позволить мне продолжать использовать устаревший генератор ключей (и, следовательно, совместимость с предыдущим сеансом с Rails 3), позволяя secret_key_base быть пустым.
Rails::Application.class_eval do
# the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
fail "I'm sorry, Dave, there 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
Я с тех пор переформатировал патч отправил его Rails в качестве запроса Pull
У меня была такая же проблема после того, как я использовал файл .gitignore из https://github.com/github/gitignore/blob/master/Rails.gitignore
Все прошло отлично после того, как я прокомментировал следующие строки в файле .gitignore.
config/initializers/secret_token.rb
config/secrets.yml
secret.yml
илиsecrets.yml
?