2012-06-24 20 views
15

Estoy trabajando en una aplicación web, alojando el código fuente en Github y ejecutando la aplicación en Heroku. Todo funciona bien, pero tengo un problema que no puedo entender. Antes de implementar mi código, ejecuto algunas secuencias de comandos para optimizar el código (minificación, concatenación de archivos, etc.). La aplicación heroku solo usa la versión optimizada de la aplicación.Estrategias de implementación de Heroku + Github

Básicamente, tengo dos carpetas: dev y production. Dev contiene el código fuente que escribo, production es producido por mis scripts de compilación (utilizo grunt y requirejs). Actualmente, ambas carpetas están en mi repositorio de Git y ambas se envían a Github y Heroku. Lo que preferiría es tener solo dev en Github y solo production en Heroku. Leí algunos artículos sobre cómo configurar diferentes ramas para Heroku, como described in this blog. ¿Podría configurar una rama de producción y solo tener la carpeta production ahí mientras mantengo la carpeta dev en mi rama principal? ¿O necesitaría repositorios separados?

¿Alguien ha intentado algo similar? Supongo que esto no es algo fuera de lo común.

Respuesta

7

Es posible que desee considerar el uso del archivo heroku .slugignore (ref https://devcenter.heroku.com/articles/slug-compiler).

Este archivo le permitirá eliminar la carpeta dev del paquete que heroku implementa en cada instancia del servidor, al tiempo que le permite conservar todo su código en el mismo repositorio.

La raíz del problema es pensar en la estrategia de implementación como una en la que carga bits finales a su servidor, donde los bits son un artefacto de la construcción de su repositorio. En tales casos, las construcciones generalmente se almacenan y archivan por separado de la fuente.

El modelo de Heroku es ligeramente diferente de este en el sentido de que asume su repositorio es el artefacto para implementar. La diferencia es leve, pero en su caso, solo significa que debe enviar a su repositorio los bits que desea que heroku sirva.

Otra forma de pensar es que podría hacerlo sin su carpeta production, y como parte del inicio de su servidor, la secuencia de comandos se ejecutará para generar los archivos de la carpeta production. Esto le permitiría eliminar la carpeta production, y mantener su repositorio limpio a costa de ejecutar este proceso en cada inicio de su servidor. Esto puede resultar prohibitivamente costoso e indeseable (hay límites en cuanto a cuánto tiempo Heroku esperará a que el servidor se inicie antes de que se rinda), pero es de esperar que ayude a proporcionar cierta claridad sobre la relación entre Heroku y Git.

+1

Esto es lo que estoy haciendo ahora ... Creé mi propio buildpack personalizado (ver https://github.com/mbuchetics/heroku-buildpack-nodejs-grunt) que usa Grunt para compilar la carpeta de producción en cada implementación. Funciona bien y puedo mantener todo el material de producción fuera del git repo. – slurmomatic

+1

Otra característica que he usado en el buildpack estándar es compatible a través de NPM. Puede agregar una secuencia de comandos '" postinstall "' a su 'paquete.json' y ejecutar código arbitrario de esta manera. https://npmjs.org/doc/scripts.html – mikegradek

2

Es un poco confuso porque:

  • su dev y production representan entornos, y son directorios con generada contenido:
    que no deberían estar en un VCS, sino que se produce de forma automática mediante un script que reconocería el entorno en el que se está ejecutando, y creará el directorio correcto en consecuencia.

  • la dev y production mencionado en el artículo que se está refiriendo a "Deploying multiple environments on Heroku (while still hosting code on Github)" representan etapas promoción, y son ramas.

El uso de las ramas es bueno, solo para aislar las variaciones de código (en dichas ramas), no para almacenar el código generado por la liberación.
Su problema particular de administración de versiones (es decir, generar la entrega correcta) debe ser administrado por una secuencia de comandos (que puede ser controlada por la versión junto con su código) y usar como gancho, por ejemplo, para generar e implementar el conjunto correcto de códigos en el lugar correcto

+0

'dev' no contiene contenido generado, ese es el código fuente que escribo allí. 'producción' es la misma pero con los archivos optimizados. Sé la diferencia de las ramas. El problema que tengo es que la implementación de Heroku se basa en repositorios de Git. Solo puedo implementar lo que hay en el repositorio. No puedo separar lo que se envía a Github y lo que se envía a Heroku (si no se usan las ramas). – slurmomatic

+0

@slurmomatic en ese caso, la respuesta de Kevin (que he votado a favor) debe estar más adaptada al proceso de gestión de versiones de Heroku que mi respuesta (más general). – VonC

5

Esta situación es un poco inusual. Pero aquí hay algunas ideas:

  • Uso un proceso similar al del artículo al que se hace referencia.
  • Crearía una sola aplicación como usted dice. Lo crearía comenzando un nuevo repositorio de git en tu carpeta dev.
  • Entonces recomendaría una estrategia de implementación similar a la descrita en esta respuesta: https://stackoverflow.com/a/8058194/267025. Me he adaptado a continuación:

Crear un archivo rake con dos tareas en ella: rake deploy:production y rake deploy:postprocess_files.Estas tareas podrían ser algo como esto:

namespace :deploy do 

    task :production do 
    puts "turn on 'maintenance page' on heroku" 
    system "heroku maintenance:on" 

    puts "deploying to production" 
    system "git push heroku-prod master" 

    puts "post processing files..." 
    system "heroku run rake production:postprocess_files" 

    puts "take off maintenance page" 
    system "heroku maintenance:off" 

    puts "done" 
    end 

    task :postprocess_files do 
    puts "run postprocessing of files on heroku" 
    ... add commands here to post process the files. 
    end 
end 

Entonces implementar en la producción utilizando rake deploy:production en lugar de empujar directamente utilizando git. El archivo rastrillo será entonces:

  1. establecer la página de mantenimiento,
  2. empuje a la producción,
  3. hacer su procesamiento posterior de los archivos,
  4. acabar con la página de mantenimiento.

Tenga en cuenta que la segunda tarea rastrillo en su archivo tiene los comandos para hacer el procesamiento posterior de los archivos y se invoca para ejecutar en heroku por la primera tarea rastrillo.

Como alternativa, es posible que pueda ampliar los recursos: tarea de precompilación que Heroku ejecuta como parte de cada implementación. Eso es esencialmente lo que estás haciendo de todos modos: preparando los activos para la implementación en la producción.

+2

+1: mecanismo de implementación más preciso – VonC

+0

No creo que esto funcione. En la documentación sobre los procesos únicos (https://devcenter.heroku.com/articles/oneoff-admin-ps) dice "Cada dyno tiene su propio sistema de archivos efímero, no compartido con ningún otro banco de pruebas, que se descarta tan pronto cuando te desconectas ". Esto funcionaría bien para los scripts de bases de datos, etc., pero no para algo que modifique el sistema de archivos. ¿O me estoy perdiendo algo? Además, ¿por qué mi situación es inusual? – slurmomatic

+1

Creo que puede estar en lo cierto; también, después de escribir esto, me di cuenta de que está implementando el código node.js y no el código de los raíles. –

Cuestiones relacionadas