La vida diaria de un desarrollador está llena de tareas monótonas y repetitivas. Afortunadamente, vivimos en una era de inteligencia pre-artificial, lo que significa que las computadoras son excelentes para manejar tareas aburridas y casi no siempre quejarse de ello! Así que configuremos un poco de automatización para hacer que nuestra rutina diaria sea un poco menos molida.
La prueba y el despliegue son dos elementos integrales del desarrollo web. Con cierta automatización combinada, se convierten en soluciones comúnmente llamadas "integración continua" (CI) y "despliegue continuo" (CD). El aspecto "continuo" de estas soluciones significa que sus proyectos se probarán y se implementarán automáticamente, lo que le permitirá centrarse más en escribir código y menos en llevarlo a los servidores..
En este tutorial, configuraremos un popular servidor de integración continua llamado Jenkins y lo sincronizaremos con GitHub para que realice pruebas cada vez que se introduzca un nuevo código. Después de eso, crearemos una solución para enviar automáticamente ese código a nuestro servidor de aplicaciones, eliminando la necesidad de que implementemos manualmente.
Usaremos DigitalOcean para crear rápida y fácilmente servidores virtuales privados (VPS) basados en la nube para alojar nuestra aplicación y Jenkins.
Nota: este tutorial asume que tiene un conocimiento básico de cómo trabajar en la línea de comandos, y que su máquina tiene Git y Node.js instalados.
Antes de que podamos probar o implementar cualquier cosa, necesitamos alguna cosa para probar y desplegar. Permítame presentarle nuestra amigable aplicación de prueba tutorial, llamada acertadamente "hola-jenkins".
Estaremos escribiendo una aplicación simple Node.js para satisfacer nuestros propósitos. No hará mucho más que mostrar una línea de texto en el navegador, pero es solo la funcionalidad suficiente para asegurarnos de que configuramos correctamente la integración continua y la implementación continua.
Ya que estaremos almacenando nuestro proyecto en GitHub, comencemos allí. Inicie sesión en (o cree) su cuenta de GitHub y cree un nuevo repositorio. Llámalo "hello-jenkins" y dale la siguiente descripción:
Mi súper aplicación de muestra para probar a Jenkins.
Para simplificar, mantengamos el repo Público. Sigue adelante y comprueba el Inicializa este repositorio con un archivo README. y seleccione la opción Nodo opción del Añadir .gitignore la lista desplegable.
Haga clic en el Crear repositorio botón, y nuestro repo estará listo.
Ahora vamos a clonar nuestro nuevo repositorio a nuestra máquina local y navegar hacia él:
git clone [email protected]:/hello-jenkins.git cd hello-jenkins
Aquí está la estructura final de nuestra aplicación:
├── .gitignore ├── app.js ├── package.json ├── README.md ├── script ├── ├── desplegar └── prueba └── test └── test.js
Abordemos esto uno por uno. El primer paso para construir cualquier aplicación Node.js es crear un paquete.json
expediente. Aquí está el nuestro:
"name": "hello-jenkins", "description": "aplicación de prueba hello jenkins", "version": "0.0.1", "private": true, "dependencies": "express": "3.12. 0 "," devDependencies ": " mocha ":" 1.20.1 "," supertest ":" 0.13.0 "
Debajo dependencias
hemos agregado exprimir
, que usaremos para ayudar a crear nuestra aplicación Node.js. Debajo Dependencias
hemos agregado moca
y supertesto
, Ambos nos ayudarán a escribir nuestras pruebas..
Ahora que nuestro paquete.json
Se define, instale nuestras dependencias de aplicaciones ejecutando:
npm instalar
Es hora de escribir nuestro código de aplicación. Crea un archivo llamado app.js
y añádele lo siguiente:
var express = require ('express'); var app = express (); app.get ('/', function (req, res) res.send ('hola mundo');); app.listen (process.env.PORT || 5000); module.exports = aplicación;
Vamos a desglosar nuestra sencilla aplicación Node.js:
exprimir
lib especificamos en nuestro paquete.json
.exprimir
para crear un nuevo aplicación.
aplicación
para responder a todas las solicitudes que llegan a la raíz de nuestro sitio (/
) con el texto "hola mundo".aplicación
en qué puerto escuchar las solicitudes (proceso.env.port
se refiere a la variable de entorno llamada "PUERTO", y si no existe, en su lugar, omitimos el puerto 5000).aplicación
disponible para otros módulos de Node.js a través de módulo.exportaciones
(Esto será útil más adelante cuando agreguemos pruebas).¡Eso es! Nuestra aplicación está lista, vamos a ejecutarla:
nodo app.js
Abre tu navegador favorito y navega hasta http: // localhost: 5000
, y deberías ver Hola Mundo sentado en toda su gloriosa claridad.
No es la aplicación de prueba más emocionante, pero funciona! Adelante, apaga nuestra aplicación Node.js con Ctrl-C, y sigamos adelante.
Es hora de escribir una prueba para nuestra aplicación: después de todo, si no tenemos nada que probar, Jenkins no tendrá nada que hacer!
Crea una carpeta llamada prueba
, y en ella crea un archivo llamado test.js
. Agregue el siguiente código a test / test.js
:
var request = require ('supertest'); var app = require ('… /app.js'); describe ('GET /', function () it ('responde with hello world', function (done) request (app) .get ('/'). expect ('hello world', done);); );
¿Cómo funciona nuestra prueba? Primero, importamos tanto el supertesto
lib y nuestro aplicación
. Luego agregamos una sola prueba, que describe lo que debería suceder cuando una OBTENER
La solicitud llega a la raíz de nuestro sitio. Le decimos a nuestra prueba que espere que la respuesta sea "hola mundo" y, si lo es, la prueba pasa.
Para ejecutar la prueba, usaremos la librería Mocha. Instalamos Mocha como parte de nuestro Dependencias
, así que simplemente ejecutaremos un comando que pasa nuestro archivo de prueba a Mocha y Mocha ejecutará nuestras pruebas:
./node_modules/.bin/mocha ./test/test.js
Cuando termine, debería ver un punto verde junto con información que dice que una prueba ha pasado. Eso significa que nuestra prueba fue exitosa! Pero escribir ese comando una y otra vez pronto producirá calambres en los dedos y contracciones en los ojos, así que hagamos un script de ayuda para que lo hagamos por nosotros (recuerde, ¡las computadoras no se aburren!).
Hacer un nuevo directorio llamado guión
, y en ella crea un archivo llamado prueba
(aviso no hay extensión). Agregue lo siguiente a guión / prueba
:
#! / bin / sh ./node_modules/.bin/mocha ./test/test.js
Ahí, ahora tenemos un script de shell para ejecutar esa línea retorcida para nosotros. Pero antes de que podamos usarlo, tenemos que otorgarle permisos de ejecución:
chmod + x script / prueba
¡Vamos a probarlo! Correr:
./ script / test
... y deberías ver la misma prueba que pasa antes.
Muy bien, tenemos una aplicación que funciona y una prueba de trabajo, así que empujemos nuestro nuevo código a GitHub:
git añadir. git commit -m 'Agregar aplicación de nodo' git push origin master
Y eso es todo: nuestra aplicación está lista y en GitHub!
Tenemos una aplicación cautivadora y cautivadora ("hola mundo" tiene una especie de poesía, ¿no te parece?), ¡Pero nadie puede verla! Vamos a cambiar eso y ejecutar nuestra aplicación en un servidor..
Para nuestras necesidades de alojamiento, recurriremos a DigitalOcean. DigitalOcean proporciona una forma rápida y sencilla de activar las instancias de VPS en la nube, lo que lo convierte en el host perfecto para nuestro área de juegos de CI / CD.
Inicie sesión en (o regístrese para) DigitalOcean y haga clic en Crear Droplet botón. Para el nombre de host, llámalo "hello-jenkins". La instancia de menor tamaño (512MB / 1 / 20GB) cubrirá nuestras necesidades y seleccionará la región geográfica más cercana a usted. A continuación, debemos elegir la imagen utilizada para crear la gota. DigitalOcean ofrece una amplia selección de sistemas operativos para elegir, pero lo que es realmente bueno es que también proporcionan imágenes diseñadas específicamente para ciertos tipos de aplicaciones..
Haga clic en el Aplicaciones pestaña, y seleccione la node-v0.10.29 en Ubuntu 14.04 Opción: esto creará un servidor que está bien bootstrapped para nuestra aplicación Node.js.
Ahora haga clic Crear Droplet, y DigitalOcean comenzará a inicializar nuestro servidor..
En un minuto, nuestro nuevo servidor debería estar listo y usted debería haber recibido un correo electrónico con las credenciales de la raíz de su servidor. Usemos esa información para iniciar sesión:
ssh [email protected]
Se le pedirá la contraseña proporcionada en el correo electrónico, y luego se lo forzará a crear una nueva contraseña (conviértala en algo muy seguro y guárdela en un lugar seguro, como una base de datos KeePass).
Ahora mismo estamos registrados como raíz
, que es el semidiós todopoderoso de Linux-land. Pero pesada es la cabeza que lleva la corona, y operando como raíz
Generalmente es una mala idea. Entonces, lo primero que querremos hacer es crear un nuevo usuario, llamémoslo "aplicación":
aplicación adduser
Tendrá que proporcionar una contraseña diferentecontraseña segura, almacenada de forma segura), y luego le hará una serie de preguntas opcionales.
Queremos cambiar a nuestro aplicación
usuario, pero antes de cerrar sesión, debemos otorgarle a nuestro nuevo usuario sudo
privilegios para que tenga la capacidad de realizar acciones administrativas:
usermod -a -G aplicación sudo
Ahora cierra la conexión con salida
, y luego conectar como aplicación
:
ssh [email protected]
Se le pedirá la aplicación
contraseña del usuario, y luego debería estar conectado y listo para comenzar.
Vamos a poner nuestra aplicación en la máquina. Gracias a las imágenes de la aplicación de DigitalOcean, nuestra máquina viene con Node.js y npm preinstalados, pero aún necesitamos instalar Git:
sudo apt-get install git
Se le pedirá su contraseña (ya que está usando sudo
), y tendrás que confirmar la instalación con Y. Una vez instalado Git, podemos usarlo para obtener nuestra aplicación de GitHub.
Copie la URL de clonación HTTPS de la página GitHub del proyecto, y luego clone el repositorio a su carpeta de inicio en el servidor:
cd git clone https://github.com//hello-jenkins.git
Ahora nuestra aplicación está en nuestro servidor, en una carpeta llamada "hello-jenkins". Vamos a navegar en eso:
cd hola-jenkins
Lo primero que debemos hacer es instalar las dependencias de la aplicación:
npm install --production
Una vez hecho esto, podemos ejecutar nuestra aplicación! Hazlo girar con:
nodo app.js
… Y navegue hasta la dirección IP de su servidor en su navegador.
Pero espera, ¡no funciona! Cual es el trato?
Bueno, recordemos esta línea de código en nuestra app.js
:
app.listen (process.env.PORT || 5000);
En este momento, no tenemos una PUERTO
conjunto de variables de entorno, por lo que nuestra aplicación está predeterminada para el puerto 5000 y debe adjuntar el puerto a la dirección IP en el navegador (http: //YOUR.SERVER.IP.ADDRESS: 5000
).
Entonces, ¿cómo conseguimos que nuestra aplicación funcione como se espera, sin tener que especificar el puerto? Bueno, cuando un navegador realiza una solicitud HTTP, se establece de manera predeterminada el puerto 80. Por lo tanto, solo necesitamos configurar nuestra PUERTO
variable de entorno a 80
.
Fijaremos nuestras variables de entorno en el / etc / medio ambiente
Archivo en el servidor: este archivo se carga al iniciar sesión y las variables establecidas estarán disponibles globalmente para todas las aplicaciones. Abre el archivo:
sudo nano / etc / environment
Verás que ahora mismo el CAMINO
se está configurando en este archivo. Agregue la siguiente línea después de esto:
PORT = 80
Entonces escribe Ctrl-X, Y, y Entrar para guardar y salir. Cierre de sesión del servidor (salida
) y SSH de nuevo en (esto cargará la nueva variable de entorno).
Una última pequeña tarea: ejecutar una aplicación en el puerto 80 requiere privilegios de root, pero ejecutar sudo node app.js
No conservaremos las variables de entorno que hemos configurado. Para solucionar esto, habilitaremos nodo
tener la capacidad de ejecutarse en el puerto 80 sans sudo
:
sudo setcap cap_net_bind_service = + ep / usr / local / bin / node
Deberias hacer eso. Ahora ejecuta:
nodo app.js
Navegar a http: //YOUR.SERVER.IP.ADDRESS
, y verás Hola Mundo!
En este momento, nuestra aplicación solo se ejecuta mientras ejecutamos el proceso; si lo cerramos, nuestro sitio ya no está disponible. Lo que necesitamos es una manera de mantener nuestra aplicación Node.js ejecutándose en segundo plano. Para eso, usaremos para siempre. El primer paso es instalarlo globalmente:
sudo npm instalar -g para siempre
Ahora, en lugar de iniciar nuestra aplicación con nodo app.js
, usaremos
para siempre iniciar app.js
Tenga en cuenta que, en lugar de que el proceso se cuelgue en la ejecución, sale inmediatamente y le devuelve el control. Esto se debe a que el servidor Node.js se está ejecutando en segundo plano. Ahora no tenemos que preocuparnos de que nuestro servidor se apague al cerrar la sesión del servidor. Siempre
Incluso reiniciará automáticamente nuestra aplicación si sucede a fallar!
Para detener nuestra aplicación, podemos ejecutar:
siempre parada
Por ahora, sigamos funcionando, y sigamos con Jenkins..
Estaremos alojando nuestro servidor Jenkins en un droplet separado de DigitalOcean. Vamos a girar eso ahora.
Cree una nueva gota con el nombre de host "jenkins-box". Escoger 512MB / 1 / 20GB de nuevo, junto con la misma ubicación y el mismo tipo de aplicación (node-v0.10.29 en Ubuntu 14.04) como con la gota anterior.
Hacer clic Crear Droplet y una vez que haya finalizado, use las credenciales que se le enviaron por correo electrónico para iniciar sesión a través de SSH (tendrá que establecer una nueva contraseña, como antes).
Como antes, deberíamos crear un nuevo usuario antes de hacer cualquier otra cosa. Esta vez llamémoslo administración
:
adduser admin usermod -a -G sudo admin
Cerrar sesión como raíz
e iniciar sesión como el recién creado administración
.
Dado que el propósito de Jenkins es recuperar nuestro proyecto y ejecutar sus pruebas, nuestra máquina necesita tener todas las dependencias del proyecto instaladas. Reflejamos esta instancia con la aplicación Node.js de DigitalOcean, por lo que Node.js y npm ya están instalados. Pero todavía necesitamos instalar Git:
sudo apt-get install git
El siguiente es Jenkins. La instalación de Jenkins es bastante simple, tendremos apt-get
hacer todo el trabajo pesado El único inconveniente es que necesitamos añadir un nuevo apto
repositorio antes de iniciar la instalación:
sudo wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary /> /etc/apt/sources.list.d/jenkins.list' sudo apt-get update
Ahora podemos instalar Jenkins:
sudo apt-get install jenkins
Una vez completado, Jenkins se ejecutará y estará disponible en el puerto 8080. Navegue por su navegador a la caja de Jenkins
Dirección IP en el puerto 8080 y verá la página de inicio de Jenkins.
Haga clic en el Manejar jenkins enlace, y luego el Administrar complementos enlazar. Cambiar a la Disponible pestaña, y busca el Plugin GitHub. Haga clic en el Instalar casilla de verificación, y luego la Descargar ahora e instalar después de reiniciar botón.
Esto iniciará la secuencia de instalación. El complemento GitHub tiene varias dependencias, por lo que se instalarán varios complementos. En la parte inferior de la página, verifique la Reinicie Jenkins cuando se complete la instalación y no se estén ejecutando trabajos - Esto hará que Jenkins se reinicie una vez que se completen las instalaciones..
Una vez que Jenkins se haya reiniciado, es hora de agregar nuestro proyecto. Haga clic en el Nuevo artículo botón. Utilice "hello-jenkins" para el nombre del elemento, seleccione Construye un proyecto de software de estilo libre, y haga clic en el botón etiquetado DE ACUERDO.
Una vez que el proyecto esté configurado, se encontrará en la página de configuración del proyecto. Agregue la URL de GitHub de nuestro proyecto a la Proyecto GitHub caja:
https://github.com// hola-jenkins
A continuación, seleccione la Git opción bajo Gestión de código fuente. En los campos recién aparecidos, agregue la URL a nuestro repositorio de proyectos de GitHub al URL del repositorio campo:
https://github.com//hello-jenkins.git
Desplácese un poco más hacia abajo y haga clic en el cuadro para habilitar Construir cuando un cambio es empujado a GitHub. Con esta opción marcada, nuestro proyecto se construirá cada vez que empujemos a nuestro repositorio de GitHub. Por supuesto, necesitamos que Jenkins sepa qué hacer cuando se ejecuta una compilación. Haga clic en el Añadir paso de compilación desplegable, y seleccione Ejecutar shell. Esto hará un Mando diálogo disponible, y lo que pongamos en este diálogo se ejecutará cuando se inicie una construcción. Agregue lo siguiente a esto:
npm instalar ./script/test
Nuestra construcción consta de dos pasos. En primer lugar, instala nuestras dependencias de aplicaciones. Entonces se ejecuta ./ script / test
para ejecutar nuestras pruebas.
Haga clic enSalvar".
Para finalizar la configuración de la integración, diríjase al repositorio de GitHub y haga clic en Ajustes. Haga clic en el Webhooks y Servicios pestaña, y luego la Añadir servicio desplegable. Selecciona el Jenkins (plugin GitHub) Servicio.
Agregue lo siguiente como Jenkins gancho url:
http: //JENKINS.SERVER.IP.ADDRESS: 8080 / github-webhook /
Hacer clic Añadir servicio. Nuestro proyecto ya está listo para su primera prueba de integración continua.!
Vamos a darle algo para probar. Abrir app.js
Localmente y cambiar esta línea:
res.send ('hola mundo');
… a esto:
res.send ('hola jenkins');
Guarda el cambio y confía en él:
git añadir. git commit -m 'Cambiar a hola jenkins'
Ahora mantén tus ojos en Jenkins mientras presionas tus cambios en GitHub:
git push master master
Después de uno o dos segundos, debería ver que se ha iniciado un nuevo trabajo para nuestro hola-jenkins
proyecto en Jenkins - nuestros trabajos de integración continua!
Pero… ¡el trabajo falla! Por qué?
Bueno, recuerde que nuestra prueba espera que la llamada raíz devuelva "hola mundo", pero la hemos cambiado a "hola jenkins". Así que vamos a cambiar las expectativas de nuestra prueba. Intercambia esta línea:
request (app) .get ('/'). expect ('hola mundo', listo);
... con esta línea:
request (app) .get ('/'). expect ('hello jenkins', listo);
Guarda, compromete y presiona de nuevo:
git añadir. git commit -m 'Prueba de conmutación para hla jenkins' git push origin master
Mira a Jenkins: una vez más, verás que una compilación se inicia automáticamente, y esta vez, tiene éxito!
Este es el flujo de la integración continua. El servidor de prueba está probando continuamente cualquier código nuevo que presione, por lo que se le informa rápidamente de cualquier prueba fallida.
Bien, entonces estamos probando automáticamente nuestros cambios, pero ¿qué hay de implementar esos cambios? No hay problema!
Si ha estado observando de cerca, sin duda habrá notado que algo falta en nuestro proyecto hasta ahora. En la estructura del proyecto al comienzo del tutorial, existe una script / desplegar
archivo, pero todavía tenemos que hacer ningún archivo de este tipo. Bueno, ahora lo haremos!
Pero primero, vamos a discutir cómo funcionará la implementación. Nuestro script (ejecutado por el paso de compilación de Jenkin) iniciará sesión en el servidor de aplicaciones a través de SSH, navegará a nuestra carpeta de aplicaciones, actualizará la aplicación y luego reiniciará el servidor. Antes de escribir nuestro script de implementación, debemos manejar cómo nuestro servidor Jenkins se SSH en nuestro servidor de aplicaciones.
Hasta ahora, hemos accedido a nuestros servidores ingresando contraseñas manualmente, pero este enfoque no funcionará para scripts automatizados. En su lugar, crearemos una clave SSH que el servidor Jenkins utilizará para autenticarse con el servidor de aplicaciones..
Cuando Jenkins se instala, crea un nuevo usuario llamado Jenkins
. Jenkins ejecuta todos los comandos con este usuario, por lo que necesitamos generar nuestra clave con el Jenkins
Usuario para que tenga el acceso adecuado a él..
Mientras está conectado como administración
sobre el caja de Jenkins
, Ejecuta lo siguiente:
sudo su
Proporcione su administración
contraseña, y te cambiará a la raíz
usuario. Luego ejecuta:
Su Jenkins
Ahora estás actuando como el Jenkins
usuario. Generar una clave SSH:
ssh-keygen -t rsa
Guarde el archivo en la ubicación predeterminada (/var/lib/jenkins/.ssh/id_rsa
), y asegúrese de no utilizar una frase de contraseña (de lo contrario, el acceso SSH requerirá una contraseña y no funcionará cuando sea automatizado).
A continuación, debemos copiar la clave pública que se creó. Ejecuta esto:
cat ~ / .ssh / id_rsa.pub
... y copiar la salida. Debe ser una cadena larga que comience con "ssh-rsa" y que termine con "jenkins @ jenkins-box".
Cerrar sesión de caja de Jenkins
y vuelva a iniciar sesión en nuestro servidor de aplicaciones (hola-jenkins
) como el aplicación
usuario. Necesitamos crear un archivo llamado authorized_keys
en nuestro aplicación
usuario.ssh
carpeta:
mkdir ~ / .ssh nano ~ / .ssh / authorized_keys
Pegue la clave pública que copió, y luego Ctrl-X/Y/Entrar para guardar y salir. Para que este archivo funcione correctamente, debe tener establecidos permisos estrictos:
chmod 700 ~ / .ssh chmod 600 ~ / .ssh / *
Regresa a la Jenkins
cuadro, cambiar a la Jenkins
usuario, y verifique que pueda iniciar sesión en nuestro servidor de aplicaciones sin ingresar una contraseña:
ssh [email protected]
Debe iniciar sesión correctamente en el servidor de aplicaciones sin tener que ingresar la contraseña. Con eso establecido, ahora podemos recurrir a la implementación..
Crea un archivo en el guión
carpeta llamada desplegar
(aviso no hay extensión). Agregue lo siguiente a script / desplegar
:
#! / bin / sh ssh [email protected] <Vayamos a través de esto:
- Primero, iniciamos sesión en el servidor de aplicaciones como
aplicación
usuario.- Luego navegamos a nuestra carpeta de aplicaciones y actualizamos a la última versión de GitHub.
- Después de eso, instalamos nuestras dependencias..
- Finalmente, una vez que nuestro código de aplicación se actualiza, reiniciamos nuestro servidor con
para siempre reiniciar
.Haga nuestro nuevo archivo de script ejecutable:
chmod + x script / deployAgrega este nuevo archivo y confía en él:
git añadir. git commit -m 'Agregar script de implementación'Pero no empujemos del todo todavía. Primero, vuelva a la configuración de nuestro proyecto en Jenkins y desplácese hasta el comando de compilación. Añade esta nueva línea al final de la misma:
./ script / deployGuarde el proyecto Jenkins.
Ahora sigue adelante y empuja a GitHub, y observa cómo Jenkins construye automáticamente. Una vez que la compilación esté terminada (debería tener éxito), navegue su navegador a la IP de nuestro servidor de aplicaciones. ¡Presto! Nuestro emocionante "hola mundo" ha sido reemplazado por un estimulante "hola jenkins"!
Nuestra aplicación ahora se está desplegando continuamente!
Todo bien que se automatiza bien
Uf. Eso fue todo un paseo!
Al final, hemos configurado con éxito tanto la integración continua y Implementación continua, que proporciona un muy buen nivel de automatización en nuestras vidas diarias de desarrolladores. Recuerde, las computadoras no se aburren, así que mientras manejan las pruebas y la implementación, son libres de hacer cosas importantes, como hacerse un sándwich. Así que ve a hacer ese sándwich y cómelo como un campeón de automatización.!