Compartir comentarios
Las respuestas se generan en base a la documentación.

Automatiza tus construcciones con GitHub Actions

Requisitos previos

Completa todas las secciones anteriores de esta guía, comenzando con Contenerizar una aplicación Node.js.

También debes tener:


Descripción general

En esta sección, configurarás un pipeline de CI/CD utilizando GitHub Actions para hacer lo siguiente de forma automática:

  • Construir tu aplicación Node.js dentro de un contenedor Docker.
  • Ejecutar pruebas unitarias y de integración, garantizando que tu aplicación cumpla con estándares sólidos de calidad de código.
  • Realizar escaneos de seguridad y evaluación de vulnerabilidades.
  • Enviar imágenes listas para producción a Docker Hub.

Conecta tu repositorio de GitHub a Docker Hub

Para permitir que GitHub Actions construya y envíe imágenes de Docker, almacenarás de forma segura tus credenciales de Docker Hub en tu nuevo repositorio de GitHub.

Paso 1: Conecta tu repositorio de GitHub a Docker Hub

  1. Crea un Token de acceso personal (PAT) desde Docker Hub.

    1. Desde tu cuenta de Docker Hub, ve a Account Settings → Security (Configuración de la cuenta → Seguridad).
    2. Genera un nuevo token de acceso con permisos de Read/Write (Lectura/Escritura).
    3. Nómbralo con algo descriptivo, como docker-nodejs-sample.
    4. Copia y guarda el token; lo necesitarás en el paso 4.
  2. Crea un repositorio en Docker Hub.

    1. Desde tu cuenta de Docker Hub, selecciona Create a repository (Crear un repositorio).
    2. Para el nombre del repositorio (Repository Name), utiliza algo descriptivo; por ejemplo: nodejs-sample.
    3. Una vez creado, copia y guarda el nombre del repositorio; lo necesitarás en el paso 4.
  3. Crea un nuevo repositorio en GitHub para tu proyecto de Node.js.

  4. Agrega las credenciales de Docker Hub como secretos en tu repositorio de GitHub.

    En tu repositorio de GitHub recién creado:

    1. Desde Settings (Configuración), ve a Secrets and variables → Actions → New repository secret (Secretos y variables → Actions → Nuevo secreto de repositorio).

    2. Agrega los siguientes secretos:

    NombreValor
    DOCKER_USERNAMETu nombre de usuario de Docker Hub
    DOCKERHUB_TOKENTu token de acceso de Docker Hub (creado en el Paso 1)
    DOCKERHUB_PROJECT_NAMETu nombre de proyecto de Docker (creado en el Paso 2)

    Con estos secretos, GitHub Actions puede autenticarse de forma segura con Docker Hub durante los flujos de trabajo automatizados.

  5. Conecta tu proyecto local a GitHub.

    Vincula tu proyecto local docker-nodejs-sample al repositorio de GitHub que acabas de crear ejecutando el siguiente comando desde la raíz de tu proyecto:

    $ git remote set-url origin https://github.com/{tu-nombre-de-usuario}/{nombre-de-tu-repositorio}.git
    
    Important

    Reemplaza {tu-nombre-de-usuario} y {nombre-de-tu-repositorio} con tu usuario y nombre de repositorio reales de GitHub.

    Para confirmar que tu proyecto local está correctamente conectado al repositorio remoto de GitHub, ejecuta:

    $ git remote -v
    

    Deberías ver una salida similar a:

    origin  https://github.com/{tu-nombre-de-usuario}/{nombre-de-tu-repositorio}.git (fetch)
    origin  https://github.com/{tu-nombre-de-usuario}/{nombre-de-tu-repositorio}.git (push)
    

    Esto confirma que tu repositorio local está vinculado adecuadamente y listo para enviar tu código fuente a GitHub.

  6. Envía tu código fuente a GitHub.

    Sigue estos pasos para confirmar y enviar tu proyecto local a tu repositorio de GitHub:

    1. Prepara todos los archivos para el commit.

      $ git add -A
      

      Este comando prepara todos los cambios (incluyendo archivos nuevos, modificados y eliminados), alistándolos para el commit.

    2. Confirma tus cambios (commit).

      $ git commit -m "Initial commit with CI/CD pipeline"
      

      Este comando crea un commit que toma una captura de los cambios preparados con un mensaje descriptivo.

    3. Envía el código a la rama main.

      $ git push -u origin main
      

      Este comando envía tus commits locales a la rama main del repositorio remoto de GitHub y establece la rama de seguimiento (upstream).

Una vez completado, tu código estará disponible en GitHub y cualquier flujo de trabajo de GitHub Actions que hayas configurado se ejecutará automáticamente.

Note

Conoce más sobre los comandos de Git utilizados en este paso:

  • Git add – Prepara los cambios (nuevos, modificados, eliminados) para el commit
  • Git commit – Guarda una captura de tus cambios preparados
  • Git push – Sube los commits locales a tu repositorio de GitHub
  • Git remote – Visualiza y gestiona las URLs de los repositorios remotos

Paso 2: Configura el flujo de trabajo

Ahora crearás un flujo de trabajo de GitHub Actions que construya tu imagen de Docker, ejecute las pruebas y envíe la imagen a Docker Hub.

  1. Desde tu repositorio en GitHub, selecciona la pestaña Actions en el menú superior.

  2. Cuando se te solicite, selecciona Set up a workflow yourself (Configurar un flujo de trabajo por ti mismo).

    Esto abre un editor integrado para crear un nuevo archivo de flujo de trabajo. Por defecto, se guardará en: .github/workflows/main.yml

  3. Agrega la siguiente configuración de flujo de trabajo al nuevo archivo:

name: CI/CD – Node.js Application with Docker

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    types: [opened, synchronize, reopened]

jobs:
  test:
    name: Ejecutar pruebas de Node.js
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:18-alpine
        env:
          POSTGRES_DB: todoapp_test
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

    steps:
      - name: Descargar código
        uses: actions/checkout@v6

      - name: Configurar Docker Buildx
        uses: docker/setup-buildx-action@v4

      - name: Almacenar en caché dependencias de npm
        uses: actions/cache@v5
        with:
          path: ~/.npm
          key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
          restore-keys: ${{ runner.os }}-npm-

      - name: Construir imagen de prueba
        uses: docker/build-push-action@v7
        with:
          context: .
          target: test
          tags: nodejs-app-test:latest
          platforms: linux/amd64
          load: true
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

      - name: Ejecutar pruebas dentro del contenedor
        run: |
          docker run --rm \
            --network host \
            -e NODE_ENV=test \
            -e POSTGRES_HOST=localhost \
            -e POSTGRES_PORT=5432 \
            -e POSTGRES_DB=todoapp_test \
            -e POSTGRES_USER=postgres \
            -e POSTGRES_PASSWORD=postgres \
            nodejs-app-test:latest
        env:
          CI: true
        timeout-minutes: 10

  build-and-push:
    name: Construir y enviar imagen Docker
    runs-on: ubuntu-latest
    needs: test

    steps:
      - name: Descargar código
        uses: actions/checkout@v6

      - name: Configurar Docker Buildx
        uses: docker/setup-buildx-action@v4

      - name: Almacenar en caché capas de Docker
        uses: actions/cache@v5
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: ${{ runner.os }}-buildx-

      - name: Extraer metadatos
        id: meta
        run: |
          echo "REPO_NAME=${GITHUB_REPOSITORY##*/}" >> "$GITHUB_OUTPUT"
          echo "SHORT_SHA=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"

      - name: Iniciar sesión en Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Construir y enviar imagen de producción multi-arquitectura
        uses: docker/build-push-action@v7
        with:
          context: .
          target: production
          push: true
          platforms: linux/amd64,linux/arm64
          tags: |
            ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:latest
            ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKERHUB_PROJECT_NAME }}:${{ steps.meta.outputs.SHORT_SHA }}
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

Este flujo de trabajo realiza las siguientes tareas para tu aplicación Node.js:

  • Se activa con cada push (empuje) o pull request (solicitud de extracción) en la rama main.
  • Construye una imagen Docker de prueba usando la etapa test.
  • Ejecuta las pruebas en un entorno contenerizado.
  • Detiene el flujo de trabajo si alguna prueba falla.
  • Almacena en caché las capas de construcción de Docker y las dependencias de npm para ejecuciones más rápidas.
  • Se autentica en Docker Hub usando secretos de GitHub.
  • Construye una imagen usando la etapa production.
  • Etiqueta y envía la imagen a Docker Hub con las etiquetas latest y el SHA corto del commit.
Note

Para obtener más información sobre docker/build-push-action, consulta el README de la GitHub Action.


Paso 3: Ejecuta el flujo de trabajo

Después de agregar tu archivo de flujo de trabajo, activa el proceso de CI/CD.

  1. Confirma y envía tu archivo de flujo de trabajo

    Desde el editor de GitHub, selecciona Commit changes… (Confirmar cambios...).

    • Este push activa automáticamente el pipeline de GitHub Actions.
  2. Monitorea la ejecución del flujo de trabajo

    1. Desde tu repositorio de GitHub, ve a la pestaña Actions.
    2. Selecciona la ejecución del flujo de trabajo para seguir cada paso: test, build, security y (si es exitoso) push y deploy.
  3. Verifica la imagen de Docker en Docker Hub

    • Después de una ejecución exitosa del flujo de trabajo, visita tus repositorios de Docker Hub.
    • Deberías ver una nueva imagen en tu repositorio con:
      • Nombre del repositorio: ${nombre-de-tu-repositorio}
      • Las etiquetas incluyen:
        • latest – representa la construcción exitosa más reciente; ideal para pruebas rápidas o despliegue.
        • <short-sha> – un identificador único basado en el hash del commit, útil para el seguimiento de versiones, reversiones y trazabilidad.
Tip

Para mantener la calidad del código y evitar pushes directos accidentales, habilita reglas de protección de ramas:

  • Desde tu repositorio de GitHub, ve a Settings → Branches (Configuración → Ramas).
  • En Branch protection rules (Reglas de protección de ramas), selecciona Add rule (Agregar regla).
  • Especifica main como el nombre de la rama.
  • Habilita opciones como:
    • Require a pull request before merging (Requerir una solicitud de extracción antes de fusionar).
    • Require status checks to pass before merging (Requerir que las comprobaciones de estado pasen antes de fusionar).

Esto garantiza que solo el código probado y revisado se fusione en la rama main.


Resumen

En esta sección, configuraste un pipeline de CI/CD completo para tu aplicación Node.js contenerizada usando GitHub Actions.

Lo que lograste:

  • Creaste un nuevo repositorio de GitHub específicamente para tu proyecto.
  • Generaste un token de acceso de Docker Hub y lo agregaste como secreto de GitHub.
  • Creaste un flujo de trabajo de GitHub Actions que:
    • Construye tu aplicación en un contenedor Docker.
    • Ejecuta pruebas en un entorno contenerizado.
    • Envía una imagen a Docker Hub si las pruebas pasan.
  • Verificaste que el flujo de trabajo se ejecuta con éxito.

Tu aplicación Node.js ahora cuenta con pruebas y despliegue automatizados.


Recursos relacionados

Profundiza en la automatización y las mejores prácticas para aplicaciones contenerizadas:


Próximos pasos

A continuación, aprende cómo puedes desplegar tu aplicación Node.js contenerizada en Kubernetes con una configuración lista para producción. Esto te ayudará a asegurar que tu aplicación se comporte como se espera en un entorno similar al de producción, reduciendo sorpresas durante el despliegue.