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

Automatiza tus construcciones con GitHub Actions

Prerrequisitos

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

También debes tener:


Descripción general

En esta sección, configurarás un flujo de trabajo (pipeline) de CI/CD usando GitHub Actions para realizar de forma automática lo siguiente:

  • Construir tu aplicación Next.js dentro de un contenedor Docker.
  • Ejecutar pruebas en un entorno consistente.
  • Subir la imagen lista para producción a Docker Hub.

Integrar GitHub y Docker Hub

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

Paso 1: Conectar tu repositorio de GitHub a Docker Hub

  1. Crea un Token de Acceso Personal (PAT) desde Docker Hub

    1. Ve a tu cuenta de Docker Hub → Account Settings → Security.
    2. Genera un nuevo Access Token con permisos de Read/Write (lectura/escritura).
    3. Nómbralo con algo como nextjs-sample.
    4. Copia y guarda el token — lo necesitarás en el Paso 4.
  2. Crea un repositorio en Docker Hub

    1. Ve a tu cuenta de Docker Hub → Create a repository.
    2. Para el nombre del repositorio, usa algo descriptivo — por ejemplo: nextjs-sample.
    3. Una vez creado, copia y guarda el nombre del repositorio — lo necesitarás en el Paso 4.
  3. Crea un nuevo repositorio de GitHub para tu proyecto de Next.js.

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

    In tu repositorio de GitHub recién creado:

    1. Navega a: Settings → Secrets and variables → Actions → New repository secret.

    2. Agrega los siguientes secretos:

    NameValue
    DOCKER_USERNAMETu nombre de usuario de Docker Hub
    DOCKERHUB_TOKENTu token de acceso de Docker Hub (creado en el Paso 1)
    DOCKERHUB_PROJECT_NAMEEl nombre de tu proyecto de Docker (creado en el Paso 2)

    Estos secretos permiten que GitHub Actions se autentique de forma segura con Docker Hub durante los flujos de trabajo automatizados.

  5. Conecta tu proyecto local a GitHub

    Vincula tu proyecto local 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-usuario}/{nombre-de-tu-repositorio}.git
    
    Important

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

    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-usuario}/{nombre-de-tu-repositorio}.git (fetch)
    origin  https://github.com/{tu-usuario}/{nombre-de-tu-repositorio}.git (push)
    

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

  6. Sube tu código fuente a GitHub

    Sigue estos pasos para confirmar (commit) y subir (push) tu proyecto local a tu repositorio de GitHub:

    1. Prepara todos los archivos para la confirmación.

      $ git add -A
      

      Este comando prepara todos los cambios — incluyendo archivos nuevos, modificados y eliminados — preparándolos para la confirmación.

    2. Confirma tus cambios.

      $ git commit -m "Initial commit"
      

      Este comando crea una confirmación que guarda una captura de los cambios preparados con un mensaje descriptivo.

    3. Sube el código a la rama main.

      $ git push -u origin main
      

      Este comando sube tus confirmaciones 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

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

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

Paso 2: Configurar el flujo de trabajo

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

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

  2. Selecciona Set up a workflow yourself (Configura un flujo de trabajo tú mismo) cuando se te solicite.

    Esto abre un editor en línea 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:

# CI/CD – Aplicación Next.js con Docker
# Construye la aplicación, ejecuta pruebas en un contenedor y sube la imagen de producción a Docker Hub.

name: CI/CD – Aplicación Next.js con Docker

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

jobs:
  build-test-push:
    name: Build, Test and Push Docker Image
    runs-on: ubuntu-latest

    steps:
      # 1. Obtener el código fuente
      - name: Checkout source code
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      # 2. Configurar Docker Buildx
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v4

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

      # 4. Guardar dependencias de pnpm en caché
      - name: Cache pnpm dependencies
        uses: actions/cache@v4
        with:
          path: ~/.local/share/pnpm/store
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: ${{ runner.os }}-pnpm-

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

      # 6. Construir imagen de Docker de desarrollo (para ejecutar pruebas)
      - name: Build Docker image for tests
        uses: docker/build-push-action@v6
        with:
          context: .
          file: Dockerfile.dev
          tags: ${{ steps.meta.outputs.REPO_NAME }}-dev:latest
          load: true
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache,mode=max

      # 7. Ejecutar pruebas de Vitest dentro del contenedor
      # Usar la misma detección de gestor de paquetes que el Dockerfile (sin corepack en tiempo de ejecución; el usuario node no puede escribir en /usr/local/bin)
      - name: Run tests
        run: |
          docker run --rm \
            --workdir /app \
            --entrypoint "" \
            -e CI=true \
            ${{ steps.meta.outputs.REPO_NAME }}-dev:latest \
            sh -c "if [ -f package-lock.json ]; then npm run test:run; elif [ -f yarn.lock ]; then yarn test:run; elif [ -f pnpm-lock.yaml ]; then pnpm run test:run; else npm run test:run; fi"
        env:
          CI: true
          NODE_ENV: test
        timeout-minutes: 10

      # 8. Iniciar sesión en Docker Hub (solo necesario para push)
      - name: Log in to Docker Hub
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      # 9. Construir y subir imagen de producción (solo al empujar a main)
      - name: Build and push production image
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'
        uses: docker/build-push-action@v6
        with:
          context: .
          file: Dockerfile
          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 Next.js:

  • Se activa en cada push (empuje) o pull request (solicitud de extracción) dirigido a la rama main.
  • Construye una imagen de Docker de desarrollo utilizando Dockerfile.dev, optimizada para pruebas.
  • Ejecuta pruebas unitarias usando Jest dentro de un entorno contenerizado limpio para asegurar la consistencia.
  • Detiene el flujo de trabajo inmediatamente si alguna prueba falla, garantizando la calidad del código.
  • Guarda en caché tanto las capas de construcción de Docker como las dependencias de npm para ejecuciones de CI más rápidas.
  • Se autentica de forma segura con Docker Hub utilizando secretos del repositorio de GitHub.
  • Construye una imagen lista para producción utilizando el Dockerfile.
  • Etiqueta y sube la imagen final a Docker Hub con las etiquetas latest y el SHA corto para facilitar el seguimiento.
Note

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


Paso 3: Ejecutar el flujo de trabajo

Una vez que hayas agregado tu archivo de flujo de trabajo, es hora de activar y observar el proceso de CI/CD en acción.

  1. Confirma y sube tu archivo de flujo de trabajo

    Selecciona "Commit changes…" en el editor de GitHub.

    • Este empuje (push) activará automáticamente el flujo de trabajo de GitHub Actions.
  2. Monitorea la ejecución del flujo de trabajo

    1. Ve a la pestaña Actions en tu repositorio de GitHub.
    2. Haz clic en la ejecución del flujo de trabajo para seguir cada paso: construcción (build), pruebas (test) y (si tiene éxito) subida (push).
  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 de la confirmación (commit), útil para el seguimiento de versiones, reversiones (rollbacks) y trazabilidad.
Tip

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

  • Navega a tu repositorio de GitHub → Settings → Branches.
  • Bajo Branch protection rules, selecciona Add rule.
  • Especifica main como nombre de la rama.
  • Activa 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 asegura que solo el código probado y revisado se fusione en la rama main.


Resumen

En esta sección, configuraste un flujo de trabajo (pipeline) de CI/CD completo para tu aplicación Next.js contenerizada usando GitHub Actions.

Esto es lo que lograste:

  • Creaste un nuevo repositorio de GitHub específicamente para tu proyecto.
  • Generaste un token de acceso seguro para Docker Hub y lo agregaste a GitHub como un secreto.
  • Definiste un flujo de trabajo de GitHub Actions para:
    • Construir tu aplicación dentro de un contenedor Docker.
    • Ejecutar pruebas en un entorno contenerizado consistente.
    • Subir una imagen lista para producción a Docker Hub si las pruebas pasan.
  • Activaste y verificaste la ejecución del flujo de trabajo a través de GitHub Actions.
  • Confirmaste que tu imagen se publicó con éxito en Docker Hub.

Con esta configuración, tu aplicación Next.js ya está lista para pruebas automatizadas y despliegue en múltiples entornos, aumentando la confianza, la consistencia y la productividad del equipo.


Recursos relacionados

Profundiza tu comprensión sobre la automatización y las mejores prácticas para aplicaciones contenerizadas:


Próximos pasos

A continuación, aprende cómo puedes probar y depurar localmente tus cargas de trabajo de Next.js en Kubernetes antes del despliegue. Esto te ayuda a asegurarte de que tu aplicación se comporte como se espera en un entorno similar al de producción, reduciendo sorpresas durante el despliegue.