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
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.
/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".
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.
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:
.class
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.
Veamos ahora un ejemplo de como desplegar una aplicación web en Java con SASS , TypeScript y que se despliega en Apache.
.jar
.jar
de la carpeta "target" al servidor donde se va a ejecutar o copiar el .war
en el Tomcat.jar
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.
npm install sass -g
sass ./scss/main.scss ./css/main.css
npm install typescript -g
tsc --outDir ./js ./ts/*.ts
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:
Veamos ahora un ejemplo de Script de transformar SASS a CSS.
"scripts": { "compile-scss": "sass ./scss/main.scss ./css/main.css" }
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.
"scripts": { "build": ".\\scripts\\build.sh" }
src
y lo deja en dist
. Eso incluye compilar el TypeScript, el SASS, etc.npm run build
onchange permite ejecutar un comando cuando cambia algún fichero.
npm install onchange -g
onchange '**/*.js' -- echo Ha cambiado un fichero JavaScript
Ahora deberemos llamar a nuestro script de npm run build
desde maven. Usaremos el plugin de
Para ello añadiremos el siguiente XML al pom.xml
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>build-cliente</id> <phase>process-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>npm</executable> <!-- Comando npm --> <workingDirectory>${project.basedir}</workingDirectory> <arguments> <argument>run</argument> <argument>build</argument> </arguments> </configuration> </execution> </executions> </plugin>
Crea un Script en bash llamado "prueba.sh" que saque por pantalla el texto de "Hola mundo" Haz que ejecutando:
npm run holaSe ejecute el Script que acabas de crear.
¿En que carpeta debería estar el script?
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 initSe 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
Crea un Script en bash llamado "build.sh" que copie todo el contenido de la carpeta "src" en "target" y transforme el SASS en CSS. De forma que ejecutando
npm run buildSe ejecute el Script "build.sh"
Crea un Script en bash llamado "deploy.sh" que despliegue todo el contenido de la carpeta "target" en Tomcat .De forma que ejecutando
npm run deploy
Se ejecute el Script "build.sh" y "deploy.sh"
Modifica el proyecto anterior , añadiendo un Script en bash llamado "start.sh" que arranque tomcat 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 startSe ejecute el Script "start.sh"
¿Que diferencia hay entre "npm run deploy" y "./scripts/deploy.sh"