¿Cuál es un buen flujo de trabajo para el Despliegue continuo a un VPS usando Travis CI y Capistrano?

Tengo una aplicación web Ruby alojada en un VPS Digital Ocean. Bajo la configuration actual, tengo un script bash que vive en el VPS que hace lo siguiente después de la ejecución:

  • Detiene el server de aplicaciones
  • Clona el último código del repository git en el server local
  • Ejecuta migraciones de bases de datos
  • Inicia el server de aplicaciones
  • Limpiar

Obviamente, este enfoque no es escalable (o incluso bueno). Por lo tanto, estoy intentando configurar una canalización de implementación con Travis CI + Capistrano que automáticamente instala, crea, testing e implementa esta aplicación web con git push.

Hasta ahora, Travis CI realiza la installation, construcción y testing de nuestro código en cada git push, pero estamos tropezando con la mejor manera de lograr el paso de implementación. Debido a que tenemos files JS y SASS que deben comstackrse usando gulp, no podemos simplemente arrancar directamente de git en el server y ejecutarlo. Y dado que Travis CI ya está creando estos files, tenemos curiosidad de saber si es apropiado aprovechar los files comstackdos de Travis CI y enviarlos directamente desde Travis CI a nuestros serveres.

Algunas opciones que hemos considerado:


Transferencia directa SCP +

Al igual que el ejemplo de FTP de implementación personalizada en Travis CI, pudimos SCP los files creados en nuestro server y llamar a un script bash que ejecuta migraciones y reinicia el server de la aplicación.

Capistrano + Transferencia directa

Podríamos instalar Capistrano en Travis CI y usarlo para transferir directamente los files creados en Travis CI a nuestros serveres. Antes de empaquetar y enviar, necesitaríamos limpiar cualquier file / directory que no necesite ser transferido (node_modules, bower, etc.). Después de transferir el package, podríamos volver a utilizar Capistrano para extraerlo, ejecutar las migraciones de la database y reiniciar el server de la aplicación.

Para esto, ¿cómo minimizamos el time de inactividad de la implementación? ¿Y cómo gestionamos errores y retrocesos?

Capistrano + Git

Podríamos insert los files de Travis CI en una label de Git en github y usar Capistrano para extraer la label de Git en el server, ejecutar las migraciones de la database y reiniciar el server de la aplicación.

Para esto, parece que los lanzamientos de git solo deberían ser para prod, entonces, ¿cómo gestionamos los diferentes entornos (dev, stage y prod)?


De todos modos, hemos investigado bastante en línea y no hemos podido encontrar una solución para nuestras necesidades que establezca el mejor enfoque estándar para implementar desde Travis CI a un proveedor de implementación no compatible.

Dada la situación anterior, ¿cuál es la mejor forma de implementar desde Travis CI a un VPS?

Terminé usando una tarea de Capistrano para empaquetar el lanzamiento de Travis CI y uploadlo al server apropiado.

Tuve que crear un nuevo SCM en Capistrano (al que llamé Travis) que sobrescribía las tareas de creación de versiones del SCM pnetworkingeterminado.

Lo he publicado en este hilo de github: https://github.com/capistrano/capistrano/issues/722#issuecomment-54653745

Y para completar, el código personalizado de Capistrano también está debajo.

 set :scm, :git namespace :travis do desc 'Check that travis is reachable' task :check do exit 1 unless true end desc 'Package to release' task :create_release do run_locally do execute :mkdir, '-p', :'tmp' execute "tar -cz --exclude tests --exclude vendor --exclude .git --exclude node_modules --exclude tmp/#{fetch(:release_timestamp)}.tar.gz -f tmp/#{fetch(:release_timestamp)}.tar.gz ." end on release_roles :all do execute :mkdir, '-p', release_path upload! "tmp/#{fetch(:release_timestamp)}.tar.gz", "#{release_path}/#{fetch(:release_timestamp)}.tar.gz" execute "tar -xvf #{release_path}/#{fetch(:release_timestamp)}.tar.gz --directory #{release_path}" execute "rm #{release_path}/#{fetch(:release_timestamp)}.tar.gz" end run_locally do execute "rm -rf tmp" end end desc 'Determine the revision that will be deployed' task :set_current_revision do run_locally do set :current_revision, capture(:git, "rev-parse --short #{fetch(:branch)}") end end end namespace :deploy do desc 'Use Travis' task :use_travis do set :scm, :travis end before :starting, :use_travis end