ruby-on-rails - portable - how to deploy rails api in heroku
Cómo resolver el error "Falta` secret_key_base` para ''production'' environment "(Rails 4.1) (12)
Agregue config/secrets.yml
al control de versiones y despliegue de nuevo. Es posible que deba eliminar una línea de .gitignore
para que pueda confirmar el archivo.
Tuve exactamente este mismo problema y resultó que el .gitignore
Github creado para mi aplicación Rails incluía config/secrets.yml
.
Creé una aplicación de rieles (rieles 4.1) desde cero y estoy enfrentando un extraño problema que no puedo resolver.
Cada vez que trato de implementar mi aplicación en Heroku obtengo un error 500:
Faltando
secret_key_base
para elsecret_key_base
de ''producción'', establezca este valor enconfig/secrets.yml
El archivo secret.yml contiene la siguiente configuración:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
En Heroku he configurado una variable de entorno "SECRET_KEY_BASE" con el resultado del comando "rake secret". Si ejecuto "heroku config", puedo ver la variable con el nombre y el valor correctos.
¿Por qué sigo recibiendo este error?
Muchas gracias
En Nginx / Passenger / Ruby (2.4) / Rails (5.1.1) nada más funcionaba excepto:
passenger_env_var
en /etc/nginx/sites-available/default
en el bloque del servidor.
Fuente: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var
Esto funcionó para mí.
SSH en su servidor de producción y cd
en su directorio actual, ejecute bundle exec rake secret
o rake secret
, obtendrá una cadena larga como salida, copie esa cadena.
Ahora ejecuta sudo nano /etc/environment
.
Pegar en la parte inferior del archivo
export SECRET_KEY_BASE=rake secret
ruby -e ''p ENV["SECRET_KEY_BASE"]''
Donde rake secret
es la cadena que acabas de copiar, pega esa cadena copiada en lugar de rake secret
.
Reinicie el servidor y pruebe ejecutando echo $SECRET_KEY_BASE
.
He creado el archivo config/initializers/secret_key.rb
y escribí solo la siguiente línea de código:
Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]
Pero creo que la solución publicada por @Erik Trautman es más elegante;)
Editar: Ah, y finalmente encontré este consejo en Heroku: documentation :)
¡Disfrutar!
Lo que hice: en mi servidor de producción, creo un archivo de configuración (confthin.yml) para Thin (lo estoy usando) y agrego la siguiente información:
environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction
Luego lanzo la aplicación con
thin start -C /whereeveristhefieonprod/configthin.yml
Trabaja como un encanto y luego no es necesario tener la clave secreta en el control de la versión
Espero que pueda ayudar, pero estoy seguro de que se podría hacer lo mismo con Unicorn y otros.
Puede exportar las claves secretas como variables de entorno en ~/.bashrc
o ~/.bash_profile
de su servidor:
export SECRET_KEY_BASE = "YOUR_SECRET_KEY"
Y luego, puedes fuente tu .bashrc
o .bash_profile
:
source ~/.bashrc
source ~/.bash_profile
Nunca confíes tus secretos.yml
Si bien puede usar inicializadores como las otras respuestas, la forma convencional de Rails 4.1+ es usar config/secrets.yml
. La razón por la cual el equipo de Rails presenta esto está más allá del alcance de esta respuesta, pero el TL; DR es que secret_token.rb
combina la configuración y el código además de ser un riesgo de seguridad ya que el token se registra en el historial de control de fuente y el único sistema que necesita saber el token secreto de producción es la infraestructura de producción.
Debería agregar este archivo a .gitignore
manera similar a como tampoco agregaría config/database.yml
al control de fuente.
Al hacer referencia al propio código de Heroku para configurar config/database.yml
desde DATABASE_URL
en su Buildpack for Ruby , terminé bifurcando su repositorio y lo modifiqué para crear config/secrets.yml
desde la variable de entorno SECRETS_KEY_BASE
.
Dado que esta característica se introdujo en Rails 4.1, sentí que era apropiado editar ./lib/language_pack/rails41.rb
y agregar esta funcionalidad.
El siguiente es el snippet del buildpack modificado que creé en mi empresa:
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
Por supuesto, puede ampliar este código para agregar otros secretos (por ejemplo, claves de API de terceros, etc.) para que sean leídos de su variable de entorno:
...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>
De esta forma, puedes acceder a este secreto de una manera muy estándar:
Rails.application.secrets.third_party_api_key
Antes de volver a implementar su aplicación, asegúrese de establecer primero su variable de entorno:
A continuación, agrega tu buildpack modificado (o eres más que bienvenido para vincularlo al mío) con tu aplicación Heroku (consulta la documentation de Heroku) y vuelve a implementar tu aplicación.
El buildpack creará automáticamente su config/secrets.yml
partir de su variable de entorno como parte del proceso de compilación del dyno cada vez que git push
Heroku.
EDITAR: La propia documentation Heroku sugiere crear config/secrets.yml
para leer desde la variable de entorno, pero esto implica que debe verificar este archivo en el control de código fuente. En mi caso, esto no funciona bien ya que tengo secretos codificados para entornos de desarrollo y prueba que prefiero no verificar.
Tengo un parche que utilicé en una aplicación de Rails 4.1 para permitirme continuar usando el generador de claves heredado (y por lo tanto compatibilidad con sesiones anteriores con Rails 3), al permitir que la base_clave_secreta esté en blanco.
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
Desde entonces, he reformateado el parche y lo he enviado a Rails como una solicitud de extracción
Tuve el mismo problema después de usar el archivo .gitignore de https://github.com/github/gitignore/blob/master/Rails.gitignore
Todo salió bien después de que comencé las siguientes líneas en el archivo .gitignore.
config/initializers/secret_token.rb
config/secrets.yml
Tuve el mismo problema y lo resolví creando una variable de entorno para cargar cada vez que me conecté al servidor de producción y realicé una mini guía de los pasos para configurarlo:
https://gist.github.com/pablosalgadom/4d75f30517edc6230a67
Estaba usando Rails 4.1 con Unicorn v4.8.2, cuando traté de implementar mi aplicación no se inició correctamente y en el archivo unicorn.log encontré este mensaje de error:
app error: Missing `secret_key_base` for ''production'' environment, set this value in `config/secrets.yml` (RuntimeError)
Después de algunas investigaciones descubrí que Rails 4.1 cambió la forma de administrar la clave secreta, así que si lees el archivo secrets.yml ubicado en exampleRailsProject/config/secrets.yml
encontrarás algo como esto:
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Esto significa que Rails recomienda que use una variable de entorno para la base de secret_key_base
en su servidor de producción, para resolver este error debe seguir estos pasos para crear una variable de entorno para Linux (en mi caso Ubuntu) en su servidor de producción:
En el terminal de su servidor de producción, ejecute el siguiente comando:
$ RAILS_ENV=production rake secret
Esto devuelve una cadena grande con letras y números, copia eso (nos referiremos a ese código como GENERATED_CODE).
Ingresa a tu servidor
Si inicia sesión como usuario raíz, busque este archivo y edítelo:
$ vi /etc/profile
Vaya a la parte inferior del archivo ("MAYÚS + G" para la capital G en VI)
Escriba su variable de entorno con GENERATED_CODE (Presione la tecla "i" para escribir en VI), asegúrese de estar en una nueva línea al final del archivo:
$ export SECRET_KEY_BASE=GENERATED_CODE
Guarde los cambios y cierre el archivo (presionamos la tecla "ESC" y luego escribimos ": x" y "ENTER" para guardar y salir en VI).
Pero si inicia sesión como usuario normal, vamos a llamarlo "usuario_ejemplo" para este artículo, necesitará encontrar uno de estos otros archivos:
$ vi ~/.bash_profile $ vi ~/.bash_login $ vi ~/.profile
Estos archivos están en orden de importancia, lo que significa que si tiene el primer archivo, entonces no necesitaría escribir en los demás. Entonces, si encuentras estos 2 archivos en tu directorio
~/.bash_profile
y~/.profile
, solo tendrás que escribir en el primero~/.bash_profile
, porque Linux leerá solo este y el otro será ignorado.Luego, vamos al final del archivo ("MAYÚS + G" para el capital G en VI).
Y escribiremos nuestra variable de entorno con nuestro GENERATED_CODE (Presione la tecla "i" para escribir en VI), asegúrese de estar en una nueva línea al final del archivo:
$ export SECRET_KEY_BASE=GENERATED_CODE
Después de escribir el código, guarde los cambios y cierre el archivo (presionamos la tecla "ESC" y luego escribimos ": x" y "ENTER" para guardar y salir en VI).
Puede verificar que nuestra variable de entorno esté configurada correctamente en Linux con este comando:
$ printenv | grep SECRET_KEY_BASE
o con:
$ echo $SECRET_KEY_BASE
Cuando ejecutas este comando, si todo salió bien, te mostrará el CÓDIGO_ GENERADO de antes. Finalmente, con toda la configuración, deberías poder implementar sin problemas tu aplicación Rails con Unicorn u otro.
Cuando cierre su terminal de shell y vuelva a iniciar sesión en el servidor de producción, tendrá esta variable de entorno configurada y lista para usar.
¡¡Y eso es!! Espero que esta mini guía te ayude a resolver este error.
Descargo de responsabilidad: no soy un gurú de Linux o Rails, por lo que si encuentra algo incorrecto o algún error, me complacerá solucionarlo.
Voy a suponer que no tienes tus secrets.yml
verificado en el control de código fuente (es decir, está en el archivo .gitignore
). Incluso si esta no es su situación, es lo que han hecho muchas otras personas al ver esta pregunta porque tienen su código expuesto en Github y no quieren que su clave secreta flote.
Si no está en control de la fuente, Heroku no lo sabe. Así que Rails está buscando Rails.application.secrets.secret_key_base
y no se ha establecido porque Rails lo establece verificando el archivo secrets.yml
que no existe. La solución más simple es ir a su archivo config/environments/production.rb
y agregar la siguiente línea:
Rails.application.configure do
...
config.secret_key_base = ENV["SECRET_KEY_BASE"]
...
end
Esto le dice a su aplicación que configure la clave secreta usando la variable de entorno en lugar de buscarla en secrets.yml
. Me habría ahorrado mucho tiempo saber esto desde el principio.
esto funciona bien https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 para que el usuario root debería editar
$ /etc/profile
pero si no root debe poner el código de generación en el siguiente
$ ~/.bash_profile
$ ~/.bash_login
$ ~/.profile