3. Despliegue Automatizado

Despliegue Automatizado

En el tema anterior hemos visto como desplegar manualmente en los servidores Apache y Nginx. En este tema vamos a ver como hacer lo mismo pero de forma automatizada. Automatizar tareas es fundamental ya que se minimizan los errores que se cometen. Por otro lado el despliegue puede llegar a hacerse decenas de veces al día, por lo que obviamente debe estar automatizado.

Podemos pensar que instalar (desplegar) decenas de veces al día una aplicación es un poco exagerado pero en sitios web como Amazon ésto si que tiene sentido. Si en la aplicación de amazón hay un error que suele afectar al 0,1% de sus ventas. ¿Cuanto dinero pierden diariamente por tener ese error? Y en este tipo de aplicaciones se suelen estar constantemente realizando cambios y corrección de error , así que ¿porque no desplegarla en cuanto está corregido un error o añadida la nueva funcionalidad? Esto en la literatura informática se llama Continuous delivery

Estructura de carpetas

Para poder automatizar el despliegue , lo primero es tener una estructura definida de nuestro proyecto y de nuestro servidor. Durante el curso vamos a usar este esquema tanto en este módulo como en los otros módulos. El esquema he intentado que sea lo mas fiel posible a la realidad de las empresas aunque he intentado simplificarlo. Sin embargo cada empresa tendrá la estructura que se adecue al proyecto que estén desarrollando.

Estructura de carpetas.

/mi-proyecto
/src //Donde está todo el código fuente de la aplicación
/main
/java
/com
/daw
/peliculas
Main.java
/resources
/static
index.html
/assets
/img
/fonts
/media //Audios y Videos
/vendor //librerías bajadas de internet (también se puede llamar lib)
/jquery
/boostrap
/scss //Código en SASS
/css //código en CSS
/ts //Código en TypeScript
/js //código en JavaScript
/docs //Documentación de la aplicación. Es la documentación con los diagramas UML, el JavaDoc, etc.
/disenyo //Donde están las imágenes en formato Photshop o similares que estamos visualmente diseñando
/db //Ficheros ".sql" de creación de la base de datos, etc. Es todo lo necesario para tener la base de datos preparada desde cero. Incluye insertar datos que siemrpe deben estar , como por ejemplo códigos de provincias. Pero NO las inserciones de los datos del usuario.
/scripts //Scripts varios. Normalmente están relacionados con el despliegue de la aplicación. Es lo mas importante en este módulo de despliegue.
deploy.sh
build.sh
/node_modules //Carpeta que usa node para guardar lo que instalamos de NodeJS
/target //El código "compilado" de la aplicación. Eso incluye transformar de TypeScript a JavaScript o de SASS a CSS,etc.
AppPeliculas-0.0.1-SNAPSHOT.jar
package.json

Hay que fijarse que en git no se debe guardar únicamente la carpeta "src" del código fuente sino que debe guardarse la carpeta "mi-proyecto" completa. Aunque se puede hacer alguna excepción con "dist" o "node-modules". El motivo de guardar la carpeta "mi-proyecto" es debido a que realmente todas esas carpetas son las que forman el proyecto, y no únicamente la carpeta "src".

Carpeta target

La carpeta target es la mas importante para el módulo de despliegue ya que en ella estará el proyecto tal y como se va a desplegar.

En otros IDE's como NetBeans , esta carpeta puede llamarse dist

Podemos pensar que debe ser únicamente una copia de la carpeta "src" ya que el código JavaScript pero si que se pueden hacer muchos cambios en esta carpeta. Veamos algunos ejemplos:

Compilar el código fuente Java a el compilado en los ficheros .class

Minimizar el código: Hacer que ocupe menos el código JavaScript o CSS. Se hace para que las páginas web se carguen antes. Y suele consistir en quitar los comentarios, los retornos de carro, etc.

Ofuscar el código: Para evitar que alguien pueda copiar nuestro código se suele, por ejemplo , cambiar el nombre de las variables por nombres sin sentido. Normalmente se minimiza y se ofusca a la vez.

Transpilar: Es transformar el código fuente de un lenguaje en otro. Se usa:

TypeScript a JavaScript: TypeScript es un lenguaje con mayor tipado que JavaScript y se suele usar en vez de JavaScript. Como los navegadores no soportan TypeScript hay que convertirlo (transpilarlo) de TypeScript a JavaScript.

SASS a CSS: SASS es un lenguaje similar a CSS pero con mayores funcionalidades. Como los navegadores no soportan SASS hay que convertirlo (transpilarlo) de SASS a CSS. En SASS también se suele decir transformar el código de SASS a CSS en vez de decir "transpilar"

Etc.

Por ello , por ejemplo, en la carpeta "src" estaría el código en TypeScript y en la carpeta "target" estaría en JavaScript correspondiente al TypeScript.

Tareas de Automatización del despliegue

Veamos ahora un ejemplo de como desplegar una aplicación web en PHP con SASS , TypeScript y que se despliega en Apache.

Copiar el código de "src" en "dist"

Transformar el código SASS en CSS dentro de la carpeta "dist"

Transpilar el código TypeScript en JavaScript dentro de la carpeta "dist"

Borrar el código SASS de la carpeta "dist"

Borrar el código TypeScript de la carpeta "dist"

Copiar el código de la carpeta "dist" a "htdocs"

Ejecutar el "httpd.exe"

Para hacer todas esta tareas vamos a usar Scripts del sistema operativo , por ejemplo en Linux se usará "Bash" y los Script de npm que vamos a ver mas adelante.

Transformar SASS en CSS

Instalar SASS

npm install node-sass -g

Transpilar SASS en CSS

sass -o ./dist/css ./src/scss

Transformar TypeScript en JavaScript

Instalar TypeScript

npm install typescript -g

Transpilar TypeScript en JavaScript

tsc --outDir ./dist/js ./src/ts/*.ts

Scripts npm

Para hacer las tareas que acabamos de indicar, se harán scripts de Bash que se dejarán en la carpeta "/scripts" sin embargo ahí puede haber gran cantidad de Script o podemos querer usar otra carpeta u otro lenguaje. Para unificar todo esto en los proyectos web, vamos a homogeneizar la ejecución de estos scripts mediante los Scripts de npm.

En los siguientes artículos se explican los scripts npm:

npm scripts

Why npm scripts

NPM is an amazing build tool

Veamos ahora un ejemplo de Script de transformar SASS a CSS.

Crear un Script para node dentro del packaje.json

Ejecutar un Script de node.

npm run compile-scss

¿Que hemos ganado con ésto? Que ahora todas las "tareas" que tenemos que hacer en el proyecto se pueden ver en el "packaje.json" y siempre se ejecutarán como "npm run nombre-tarea"

Veamos ahora tres script que deberíamos siempre tener en cualquier proyecto.

build: Compila el código de src y lo deja en dist. Eso incluye compilar el TypeScript, el SASS, etc.

npm run build

deploy: Compila y despliega el código. Deja el contenido de dist en el servidor Apache en una carpeta de htdocs

npm run deploy

start: Inicia el servidor apache , Compila y despliega el código con cada cambio. En el siguiente apartado se explica como ejecutar un Script cuando hay un cambio en un fichero.

npm run start

Ejecutar un Script cuando algo cambia

onchange permite ejecutar un comando cuando cambia algún fichero.

Instalar onchange

npm install onchange -g

Mostrar un mensaje cada vez que cambia algo en un fichero JavaScript

onchange '**/*.js' -- echo Ha cambiado un fichero JavaScript

Ejercicios

Ejercicio 1

Crea un Script en bash llamado "prueba.sh" que saque por pantalla el texto de "Hola mundo" Haz que ejecutando:

npm run hola

Se ejecute el Script que acabas de crear.

¿En que carpeta debería estar el script?

Ejercicio 2

Crea un Script en bash llamado "init.sh" que cree las carpetas que debe tener como mínimo un proyecto Haz que ejecutando:

npm run init

Se ejecute el Script que acabas de crear.

¿En que carpeta debería estar el script?

¿Que diferencia hay entre npm init y npm run init

Ejercicio 3

Crea un Script en bash llamado "build.sh" que copie todo el contenido de la carpeta "src" en "dist" y transforme el SASS en CSS. De forma que ejecutando

npm run build

Se ejecute el Script "build.sh"

Crea un Script en bash llamado "deploy.sh" que despliegue todo el contenido de la carpeta "dist" en Apache .De forma que ejecutando

npm run deploy

Se ejecute el Script "build.sh" y "deploy.sh"

Ejercicio 4

Modifica el proyecto anterior , añadiendo un Script en bash llamado "start.sh" que arranque apache y que cuando haya un cambio en la carpeta "src" se redespliegue la aplicación en el servidor web .De forma que ejecutando

npm run start

Se ejecute el Script "start.sh"

¿Que diferencia hay entre "npm run deploy" y "./scripts/deploy.sh"