ruby-on-rails - rails - instal heroku
Rails 3 y Heroku: automáticamente "rake db: migrate" en push? (10)
Tengo una ligera molestia con mi proceso heroku push / deploy, que de otra manera ha sido un placer descubrir y usar.
Si agrego una nueva migración a mi aplicación, la única forma en que puedo subirla al servidor heroku es presionar el control remoto heroku. Esto lo carga y reinicia la aplicación. Pero no ejecuta la migración, entonces tengo que hacer heroku rake db:migrate --app myapp
, luego heroku restart --app myapp
. Mientras tanto, la aplicación está rota porque no ha ejecutado las migraciones y el código hace referencia a campos / tablas, etc. en la migración.
Debe haber una forma de cambiar el proceso de implementación para ejecutar el rake db:migrate
automáticamente como parte del proceso de implementación pero no puedo resolverlo.
¿Es algo que configuro en un cpanel de heroku? ¿Es una opción que pase al heroku desde la línea de comando? ¿Es un gancho git? ¿Alguien me puede aclarar? gracias, max
¿Qué pasa con esta simple solución de encadenamiento de comandos?
git push heroku master && heroku run rake db:migrate
Automáticamente ejecutará la migración tan pronto como la primera termine exitosamente. Es típicamente 1-2 segundos de retraso o menos.
Aquí hay una tarea de rake que lo envuelve todo en un solo liner (y también admite rollback):
https://gist.github.com/362873
Aún puede terminar implementando en la parte superior de la demostración de su jefe, pero al menos no pierde el tiempo escribiendo entre el git push
y el rake db:migrate
.
Creo que el enfoque de David Sulc es el único que garantiza que evites las solicitudes mientras la aplicación está en mal estado.
Es un poco doloroso, pero puede ser necesario en algunas circunstancias.
Como dijo, requiere que las migraciones de db no sean destructivas.
Sin embargo, puede ser difícil impulsar sus migraciones y cambios de esquema antes del resto del código, ya que el enfoque obvio (''git push heroku {revnum}'') depende de que haya verificado las migraciones antes que el resto del código.
Si aún no lo ha hecho, aún es posible hacerlo mediante una sucursal temporal:
Crea una rama, basada en la revisión de git que has enviado recientemente a heroku:
git branch <branchname> <revnum-or-tag>
Echa un vistazo a esa sucursal:
git checkout <branchname>
Si su migración de db confirma solo las migraciones contenidas y no cambia el código, seleccione las confirmaciones que contienen los cambios en la base de datos:
git cherry-pick <revnum1> <revnum2>...
Si realizó cambios en su BD en revisiones que también contenían cambios de código, puede usar ''git cherry-pick -n'' que no se confirmará automáticamente; use ''git reset HEAD'' para eliminar los archivos que no son cambios de DB del conjunto de cosas que se van a comprometer. Una vez que haya obtenido los cambios de DB, hágalos en su rama temporal.
git cherry-pick -n <revnum1> <revnum2>... git reset HEAD <everything that''s modified except db/> git status ... check that everything looks ok ... git commit
Empuje esta rama temporal hacia heroku (idealmente a una aplicación de etapas para comprobar que lo tiene correcto, ya que evitar el tiempo de inactividad es el punto total de saltar a través de estos aros)
git push heroku <branchname>:master
Ejecute las migraciones
heroku run rake db:migrate
En este punto, podría pensar que podría simplemente presionar ''maestro'' a heroku para obtener los cambios de código. Sin embargo, no puedes, ya que no es una fusión de avance rápido. La forma de proceder es fusionar el resto de ''maestro'' en su rama temporal, luego fusionarlo de nuevo a maestro, que recombina los historiales de confirmación de las dos ramas:
git checkout <branchname> git merge master git diff <branchname> master ... shouldn''t show any differences, but just check to be careful ... git checkout master git merge <branchname>
Ahora puedes enviar master al heroku como siempre, lo que hará que el resto del código cambie.
En el penúltimo paso, no estoy 100% seguro de si es necesario combinar master con {branchname}. Hacerlo de esa manera debería garantizar que se realiza una fusión de "avance rápido", lo que mantiene feliz a git cuando se presiona a heroku, pero podría obtenerse el mismo resultado al fusionar {branchname} en principal sin ese paso.
Por supuesto, si no está utilizando ''maestro'', sustituya el nombre de la rama correspondiente en los lugares relevantes anteriores.
Escribí SmartMigrate buildpack, que es un simple buildpack de Heroku para advertir de las migraciones pendientes después de una compilación ruby cada vez que se detectan nuevas migraciones. Este buildpack está destinado a ser parte de un Multipack que tiene un buildpack anterior de Ruby.
Con el debido respeto a otras soluciones aquí, este buildpack tiene 3 ventajas sobre las siguientes:
- Sin necesidad de modo de mantenimiento
- No hay necesidad de forks de buildpack ruby obsoletos que solo inserten la migración al final
- No es necesario ejecutar migraciones TODO EL TIEMPO; solo se muestra una advertencia si se detectan nuevas migraciones desde la última implementación.
He estado usando la gema heroku_san como mi herramienta de implementación por un tiempo. Es una buena herramienta pequeña y enfocada para la migración push +. Agrega algunos otros comandos de rake que facilitan el acceso a otras funciones (como la consola). Más allá de no tener que recordar migraciones de bases de datos, mi característica favorita es su archivo de configuración Heroku, así puedo nombrar todos mis servidores (producción, montaje, parque infantil4, shirley) como quiera y mantenerlos en mi cabeza.
Heroku ahora tiene la capacidad de manejar esto como parte de su función de "fase de liberación".
Puede agregar un proceso llamado release
a su Procfile
y se ejecutará durante cada implementación.
Rails> = 5 Ejemplo
release: bundle exec rails db:migrate
Ejemplo de Rails <5
release: bundle exec rake db:migrate
Solo para aquellos que buscan en Google como yo, les quiero dar una solución simple aquí.
Estoy usando Rails 4 y necesitaba agregar una tarea simple de Rake a la implementación en heroku. Como estoy usando el botón ''deploy to heroku'' en github, no hay posibilidad de ejecutar "heroku run ..." inmediatamente después del despliegue.
Lo que hice: amplié los activos estándar de la tarea de rake: limpiar que se ejecutan automáticamente durante una implementación en heroku. La tarea todavía se ejecuta normalmente, pero he adjuntado mis propias cosas a su fin. Esto se hace con el método ''mejorar'' . En el siguiente ejemplo agrego un db: migrate porque esto es probablemente lo que la mayoría de la gente quiere:
# in lib/tasks/assets_clean_enhance.rake
Rake::Task[''assets:clean''].enhance do
Rake::Task[''db:migrate''].invoke
end
Admito que esta no es la solución perfecta. Pero el heroku Ruby Buildpack aún no es compatible de ninguna otra manera. Y escribir mi propio buildback parecía un poco exagerado por algo tan simple.
Tal vez podría intentar separar las confirmaciones de su esquema (migraciones, etc.) de las confirmaciones de código (modelos, validaciones, etc.).
(Tenga en cuenta que lo siguiente asume que sus cambios de migración NO son destructivos, ya que indica que cubren la mayoría de sus casos de uso).
Su proceso de implementación podría ser:
- Presione cambios de esquema a Heroku
- emigrar
- Empujar el código de la aplicación a Heroku
Esto es, por supuesto, muy óptimo, pero es una forma efectiva de evitar el tiempo de inactividad en la situación que ha descrito: para cuando la aplicación reciba el código para los campos dinámicos, el DB ya habrá migrado.
(Por supuesto, la solución más simple sería simplemente empujar y migrar mientras su jefe sale a almorzar ;-D)
De lo contrario, incluso si las modificaciones del esquema se llevaran a cabo automáticamente, aún correría el riesgo de que se pase una solicitud justo antes de que se hayan ejecutado las migraciones.
Utilizo una tarea de rake para poner la aplicación en modo de mantenimiento, pulsar, migrar y moverla fuera del modo de mantenimiento.
Creé un buildpack personalizado que hace que Heroku ejecute rake db:migrate
automáticamente en la implementación. Es solo una bifurcación del buildpack Ruby predeterminado de Heroku, pero con la tarea rake db:migrate
añadida.
Para usarlo con tu aplicación, harías esto:
heroku config:set BUILDPACK_URL=https://github.com/dtao/rake-db-migrate-buildpack
También tenga en cuenta que para que funcione, debe habilitar la función user-env-compile Heroku Labs. Así es como lo haces:
heroku labs:enable user-env-compile
Y aquí está mi evidencia de que esto funciona: