Herramientas de usuario

Herramientas del sitio


clase:daw:daw:tema07

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
clase:daw:daw:tema07 [2026/10/29 14:20] – Fuera el despliegue por VPN+SSH: Workflows con compilar.yml en el runner de GitHub y el despliegue con runner propio claudeclase:daw:daw:tema07 [2026/10/29 19:16] (actual) – [Runners] claude
Línea 3: Línea 3:
  
 ===== Introducción ===== ===== Introducción =====
- 
-  * [[https://blog.develat.io/pipelines-ci-cd/|Integración continua y despliegue continuo]] 
-  * [[https://devopsti.wordpress.com/2014/09/26/integracion-continua-ci-entrega-continua-cd-y-despliegue-continuo-cd/|Integración continua (CI), Entrega continua (CD) y Despliegue Continuo (CD)]] 
-  * [[https://geeks.ms/jorge/2019/02/25/integracion-entrega-y-despliegue-continuo-diferencias-y-similitudes/|Integración, entrega y despliegue continuo. Diferencias y similitudes]] 
- 
 El despliegue continuo es desplegar las aplicaciones web lo más pronto posible: cada cambio que se sube al repositorio acaba en el servidor sin que nadie tenga que hacerlo a mano. El despliegue continuo es desplegar las aplicaciones web lo más pronto posible: cada cambio que se sube al repositorio acaba en el servidor sin que nadie tenga que hacerlo a mano.
  
Línea 15: Línea 10:
   - Compilarlo y pasar los tests.   - Compilarlo y pasar los tests.
   - Construir la imagen Docker.   - Construir la imagen Docker.
-  - Conectarse al servidor y arrancar la nueva versión.+  - Desplegar la nueva versión
  
 Si un paso falla, se para ahí y avisa: lo que no compila o no pasa los tests no llega al servidor. Si un paso falla, se para ahí y avisa: lo que no compila o no pasa los tests no llega al servidor.
  
-Los dos que vamos a ver son: +Existen muchas formasde hacerlo, antiguamente se hacía con una herramienta de software libre llamada [[https://www.jenkins.io/|Jenkins]] pero actualmente se usan las acciones de GitHub o GitLab , etc.
-  * [[https://www.jenkins.io/|Jenkins]]: un programa que instalamos nosotros en un servidor nuestro (por ejemplo, en un contenedor Docker) y que vigila los repositorios. +
-  * [[https://github.com/features/actions|GitHub Actions]]: viene incluido en GitHub. No hay que instalar nada: los pasos se escriben en un fichero dentro del propio repositorio y los ejecutan máquinas de GitHub.+
  
-^ ^ Jenkins ^ GitHub Actions ^ +GitHub Actions es el sistema de automatización integrado en GitHub. Cada fichero YAML dentro de ''.github/workflows/'' es un **workflow**, y en él se define: 
-| Dónde se ejecuta | En un servidor nuestro | En máquinas de GitHub | + 
-| Hay que instalarlo y mantenerlo | ✓ | | +  * **Cuándo se ejecuta:** al hacer un push, cuando tú decidas o a una hora programada. 
-| Dónde se escriben los pasos | En Jenkins | En el repositorio, en ''.github/workflows/'' | +  * **Qué se ejecuta:** las tareas (**jobs**), como compilar, pasar los tests o desplegar. Cada job se compone de pasos (**steps**), que pueden ser órdenes de shell o //actions// reutilizables hechas por otros. 
-| Sirve para repositorios fuera de GitHub | ✓ | |+  * **Dónde se ejecuta:** en un **runner**, el programa que ejecuta los jobs. Puede estar en una máquina virtual de GitHub o en una máquina tuya ([[#runners|Runners]]). 
 + 
 + 
 +Mas información: 
 +  * [[https://blog.develat.io/pipelines-ci-cd/|Integración continua y despliegue continuo]] 
 +  * [[https://devopsti.wordpress.com/2014/09/26/integracion-continua-ci-entrega-continua-cd-y-despliegue-continuo-cd/|Integración continua (CI), Entrega continua (CD) y Despliegue Continuo (CD)]] 
 +  * [[https://geeks.ms/jorge/2019/02/25/integracion-entrega-y-despliegue-continuo-diferencias-y-similitudes/|Integración, entrega y despliegue continuo. Diferencias y similitudes]]
  
-Si el proyecto está en GitHub, usa GitHub Actions. 
  
  
 ===== Workflows ===== ===== Workflows =====
-Un **workflow** es un fichero YAML dentro de la carpeta ''.github/workflows/'' del repositorio. GitHub lee esa carpeta en cada ''push'': no hay que darlo de alta en ningún sitio. El fichero tiene tres partes:+Un **workflow** es un fichero YAML dentro de la carpeta ''.github/workflows/'' del repositorio. GitHub lee esa carpeta en cada ''push'': no hay que darlo de alta en ningún sitio. El fichero tiene cuatro partes:
  
   * ''on'': cuándo se ejecuta. ''push'' con ''branches'' cuando se sube algo a esa rama; ''workflow_dispatch'' añade un botón //Run workflow// en la pestaña //Actions// para lanzarlo a mano.   * ''on'': cuándo se ejecuta. ''push'' con ''branches'' cuando se sube algo a esa rama; ''workflow_dispatch'' añade un botón //Run workflow// en la pestaña //Actions// para lanzarlo a mano.
-  * ''jobs'': los trabajos que hay que hacer. Cada uno se ejecuta en un **runner**, el que diga ''runs-on'': con ''ubuntu-latest'', un Ubuntu que GitHub crea para la ocasión y tira al acabar ([[#runners|Runners]]).+  * ''jobs'': los trabajos que hay que hacer. 
 +  * ''runs-on'': el **runner** en el que se ejecuta cada trabajo. Con ''ubuntu-24.04'', un Ubuntu que GitHub crea para la ocasión y tira al acabar; con ''self-hosted'', un runner propio ([[#runners|Runners]]). Siempre con la versión puesta, nunca ''ubuntu-latest'': cuando GitHub cambia la versión a la que apunta, los scripts que funcionaban pueden dejar de funcionar sin haber tocado nada.
   * ''steps'': los pasos de cada trabajo, en orden. Cada paso tiene un ''name'' y hace una de dos cosas:   * ''steps'': los pasos de cada trabajo, en orden. Cada paso tiene un ''name'' y hace una de dos cosas:
     * ''run'': órdenes de shell, como en una terminal. Con ''|'' se ponen varias líneas.     * ''run'': órdenes de shell, como en una terminal. Con ''|'' se ponen varias líneas.
Línea 58: Línea 57:
 jobs: jobs:
   compilar:   compilar:
-    runs-on: ubuntu-latest+    runs-on: ubuntu-24.04
     steps:     steps:
       - uses: actions/checkout@v7       - uses: actions/checkout@v7
Línea 79: Línea 78:
 Un **runner** es el programa que ejecuta los jobs de un workflow: GitHub le pasa los pasos y él los va ejecutando y le devuelve el log. Dónde está el runner lo elige ''runs-on'', y hay dos tipos: Un **runner** es el programa que ejecuta los jobs de un workflow: GitHub le pasa los pasos y él los va ejecutando y le devuelve el log. Dónde está el runner lo elige ''runs-on'', y hay dos tipos:
  
-  * **Runner de GitHub** (''runs-on: ubuntu-latest''): una máquina virtual que GitHub crea para cada job y tira al acabar. Es el del workflow de arriba.+  * **Runner de GitHub** (''runs-on: ubuntu-24.04''): una máquina virtual que GitHub crea para cada job y tira al acabar. Es el del workflow de arriba.
   * **Runner propio** (''runs-on: self-hosted''): el mismo programa, pero instalado por nosotros en un servidor nuestro. Se queda siempre en marcha esperando trabajo.   * **Runner propio** (''runs-on: self-hosted''): el mismo programa, pero instalado por nosotros en un servidor nuestro. Se queda siempre en marcha esperando trabajo.
  
Línea 95: Línea 94:
 El runner está en Internet y el servidor en el instituto, así que para desplegar tendría que entrar por VPN y SSH, con las claves guardadas como secretos: El runner está en Internet y el servidor en el instituto, así que para desplegar tendría que entrar por VPN y SSH, con las claves guardadas como secretos:
  
-<uml> +{{:clase:daw:daw:runner-github.png?800|Con el runner de GitHub: crea el runner y entra en el servidor por VPN y SSH}} 
-actor "Alumno" as alumno + 
-cloud "GitHub" { +La clave privada SSH para entrar en el servidor ([[clase:daw:proyecto:1eval:tema01#conexion_con_claves_publica_privada|Proyecto 1]]) se guarda como secreto ''SSH_KEY'', y el usuario y el servidor como ''SSH_USER'' y ''SSH_HOST''. El workflow entra por SSH y ejecuta ''deploy.sh'', que está en el //home// del usuario en el servidor: 
-  node "Repositorio" as repo + 
-  node "Runner de GitHub\n(máquina virtual nueva)" as runner +<sxh yaml;title:.github/workflows/desplegar.yml;highlight:[11,17]> 
-} +name: Desplegar 
-node "Servidor del instituto" as servidor { + 
-  component "deploy.sh" as deploy +on: 
-} +  workflow_dispatch: 
-alumno --> repo : 1. git push +  push: 
-repo --> runner : 2. crea el runner\ny le pasa el job +    branches: 
-runner --> deploy : 3. VPN + SSH +      - master 
-</uml>+ 
 +jobs: 
 +  desplegar: 
 +    runs-on: ubuntu-24.04 
 +    steps: 
 +      - name: Desplegar 
 +        run: | 
 +          echo "${{ secrets.SSH_KEY }}" > clave 
 +          chmod 600 clave 
 +          ssh -i clave -o StrictHostKeyChecking=accept-new ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "~/deploy.sh" 
 +</sxh> 
 +  * ''echo'' y ''chmod'': ''ssh'' lee la clave de un fichero, así que se escribe el secreto en uno. 
 +  * ''StrictHostKeyChecking=accept-new'': el runner es nuevo y no conoce el servidor. Sin esto, ''ssh'' pregunta si se fía de él y el workflow se queda parado esperando la respuesta. 
 +  * ''"~/deploy.sh"'': la orden que se le pasa a ''ssh'' detrás del servidor se ejecuta en el servidor, no en el runner. Va entre comillas para que ''~'' sea el //home// del servidor y no el del runner. 
 + 
 +Solo funciona si el servidor acepta SSH desde Internet. Si está detrás del router del instituto o de la empresa, antes hay que conectar la VPN en otro paso, con más secretos. O quizás ni se pueda si no hay una VPN
  
 ==== Con un runner propio ==== ==== Con un runner propio ====
Línea 113: Línea 127:
 El runner está dentro del servidor. Es él quien **pregunta a GitHub** si hay trabajo, por HTTPS, como un navegador: no hace falta abrir ningún puerto ni VPN, y funciona aunque el servidor esté detrás del router del instituto. El runner está dentro del servidor. Es él quien **pregunta a GitHub** si hay trabajo, por HTTPS, como un navegador: no hace falta abrir ningún puerto ni VPN, y funciona aunque el servidor esté detrás del router del instituto.
  
-<uml> +{{:clase:daw:daw:runner-propio.png?800|Con un runner propio: el runner pregunta a GitHub por HTTPS y ejecuta el job en local}}
-actor "Alumno" as alumno +
-cloud "GitHub" { +
-  node "Repositorio" as repo +
-} +
-node "Servidor propio" as servidor { +
-  node "Runner propio\n(servicio)" as runner +
-  component "deploy.sh" as deploy +
-} +
-alumno --> repo : 1. git push +
-repo <-- runner : 2. ¿hay trabajo? (HTTPS)\ny recibe el job +
-runner --> deploy : 3. lo ejecuta en local +
-</uml>+
  
 ==== Instalar un runner propio en Linux ==== ==== Instalar un runner propio en Linux ====
 Un runner se registra en **un** repositorio y solo ejecuta sus workflows. Se instala en el servidor con el usuario que va a desplegar, no con ''root'': Un runner se registra en **un** repositorio y solo ejecuta sus workflows. Se instala en el servidor con el usuario que va a desplegar, no con ''root'':
  
-  - En el repositorio, //Settings → Actions → Runners → New self-hosted runner//, con //Linux// y //x64//. GitHub muestra las órdenes de los pasos siguientes con el token ya puesto. El token caduca en una hora.+  - En el repositorio, //Settings → Actions → Runners → New self-hosted runner//, con //Linux// y //x64//. GitHub muestra las órdenes de los pasos siguientes: se copian de esa página, porque la de ''config.sh'' lleva el token.
   - Descargarlo:<sxh bash>   - Descargarlo:<sxh bash>
 mkdir actions-runner && cd actions-runner mkdir actions-runner && cd actions-runner
Línea 136: Línea 138:
 tar xzf ./actions-runner-linux-x64-2.338.2.tar.gz tar xzf ./actions-runner-linux-x64-2.338.2.tar.gz
 </sxh> </sxh>
-  - Registrarlo en el repositorio. Pregunta el grupo, el nombre y las etiquetas: con //Enter// se queda lo que propone.<sxh bash>+  - Registrarlo en el repositorio. ''--url'' es el repositorio y ''--token'' un **token de registro** que GitHub genera al abrir la página de //New self-hosted runner//: está en la orden ''config.sh'' del apartado //Configure// de esa página. Pregunta el grupo, el nombre y las etiquetas: con //Enter// se queda lo que propone.<sxh bash>
 ./config.sh --url https://github.com/lgonzalezmislata/Facturas --token AXQKZ7MBV3LN2RCYEUHJ4PDTD6Y2W ./config.sh --url https://github.com/lgonzalezmislata/Facturas --token AXQKZ7MBV3LN2RCYEUHJ4PDTD6Y2W
 </sxh> </sxh>
Línea 146: Línea 148:
   - En //Settings → Actions → Runners// tiene que salir como //Idle//.   - En //Settings → Actions → Runners// tiene que salir como //Idle//.
  
-El workflow de despliegue, en el repositorio del proyecto, se queda en clonar el repositorio de despliegue y lanzar ''deploy.sh'':+<note important>El token de registro **no es un token personal** de GitHub ni hay que crearlo: lo da esa página, solo sirve para registrar el runner una vez y **caduca en una hora**. Si ''config.sh'' dice que el token no vale, se recarga la página y se copia el nuevo.</note>
  
-<sxh yaml;title:.github/workflows/desplegar.yml>+==== Configurar un workflow para usar un runner ==== 
 +El workflow es el mismo que con el [[#con_el_runner_de_github|runner de GitHub]], pero sin SSH: el runner ya está en el servidor y ejecuta ''deploy.sh'' allí mismo. 
 + 
 +<sxh yaml;title:.github/workflows/desplegar.yml;highlight:[11]>
 name: Desplegar name: Desplegar
  
Línea 162: Línea 167:
     steps:     steps:
       - name: Desplegar       - name: Desplegar
-        run: | +        run: ~/deploy.sh
-          rm -rf DesplegarFacturasDocker +
-          git clone https://github.com/lgonzalezmislata/DesplegarFacturasDocker.git +
-          cd DesplegarFacturasDocker && ./deploy.sh+
 </sxh> </sxh>
  
-<note important>Los pasos se ejecutan **con el usuario que instaló el runner**, y sin terminal para escribir la contraseña de ''sudo''. Si ''deploy.sh'' usa Docker, ese usuario tiene que estar en el grupo ''docker'' (''sudo usermod -aG docker $USER'' y reiniciar el servicio).</note> +Lo que hace que el job se ejecute en nuestro servidor es ''runs-on: self-hosted''. Los pasos se ejecutan **con el usuario que instaló el runner**
- +
-<note important>El runner propio **no empieza vacío**: lo que deja una ejecución sigue ahí en la siguiente, en ''actions-runner/_work''. Por eso el workflow borra la carpeta antes de clonar.</note> +
- +
-<note warning>Un runner propio solo en **repositorios privados**: en uno público, cualquiera que abra un //pull request// puede hacer que ejecute su código en tu servidor.</note>+
  
 Más información: Más información:
clase/daw/daw/tema07.1793280007.txt.gz · Última modificación: por claude