Files
PruebaGentle/Bitacora-CICD-Gitea.md
dmolinari 840ef44670
All checks were successful
CI/CD Pipeline / backend-build (push) Successful in 2m3s
CI/CD Pipeline / frontend-build (push) Successful in 43s
CI/CD Pipeline / docker-build (push) Successful in 1m18s
fix: add image names to docker-compose and update CI pipeline with login-action
2026-04-04 19:25:52 -03:00

7.6 KiB

📖 Bitácora de Configuración CI/CD en Gitea

Fase 1: Configuración del Gitea Act-Runner

Objetivo: Levantar el contenedor que ejecutará los pipelines de Gitea (el "runner").

  • Problema 1: El contenedor del runner no iniciaba y arrojaba el error accepts at most 0 arg(s), received 1.
    • Causa: Un espacio en blanco después de la coma en la variable de entorno GITEA_RUNNER_LABELS que Bash interpretaba como un argumento adicional.
    • Solución: Eliminar el espacio y encerrar toda la declaración entre comillas dobles en el docker-compose.yml de Gitea: - "GITEA_RUNNER_LABELS=ubuntu-latest:docker://node:18-bullseye,docker:docker://repo.eldiaservicios.com/dmolinari/act-runner:latest"

Fase 2: Preparación del Proyecto y Docker Compose

Objetivo: Que el código fuente (Backend y Frontend) se construya correctamente dentro de Docker.

  • Problema 2: Error al construir la imagen del backend: ERROR: "/PruebaGentle.API.csproj" not found.

    • Causa: El "contexto" de construcción (context) estaba mal referenciado; Docker buscaba el archivo en la raíz cuando en realidad estaba dentro de la carpeta Backend/.
    • Solución: Se ajustó el docker-compose.yml del proyecto definiendo explícitamente los contextos (context: ./Backend y context: ./Frontend).
  • Problema 3: Gitea no mostraba los paquetes en la pestaña "Paquetes" del repositorio.

    • Causa: Las imágenes no tenían metadatos que le dijeran a Gitea a qué repositorio pertenecían.
    • Solución: Se agregaron etiquetas OCI (labels) al docker-compose.yml del proyecto.
  • Problema 4: Docker Compose no sabía cómo llamar a las imágenes, dando errores al intentar etiquetarlas con docker tag backend.

    • Solución: Declarar el nombre exacto de la imagen en la propiedad image: de cada servicio.

Resultado final de docker-compose.yml (Proyecto):

services:
  backend:
    image: repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest
    build:
      context: ./Backend
      dockerfile: Dockerfile
      labels:
        - "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"

  frontend:
    image: repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest
    build:
      context: ./Frontend
      dockerfile: Dockerfile
      labels:
        - "org.opencontainers.image.source=https://repo.eldiaservicios.com/dmolinari/PruebaGentle"

Fase 3: Solución de Problemas en el Pipeline (Errores de Gitea Actions)

Objetivo: Que el Action compile, inicie sesión y suba las imágenes a Gitea Registry.

  • Problema 5: Error client version 1.52 is too new. Maximum supported API version is 1.41.

    • Causa: El Docker Engine del servidor host es más antiguo que el cliente instalado en el runner. Las variables de entorno del Dockerfile se borraban al iniciar el job.
    • Solución: Forzar la compatibilidad inyectando env: DOCKER_API_VERSION: "1.41" directamente a nivel del Job en el archivo ci.yml.
  • Problema 6: Errores de Autenticación (unauthorized, cannot perform an interactive login from a non TTY device y Password required).

    • Causa: Faltaba el paso para iniciar sesión en el Registry. Al intentar pasarlo por consola, si una variable estaba vacía, Docker pedía la clave por teclado, colgando el proceso (non TTY). Además, el token por defecto de Gitea no tenía permisos de escritura para paquetes.
    • Solución:
      1. Se generó un Token de Acceso Personal (PAT) desde el perfil del usuario con permisos de lectura/escritura en Packages.
      2. Se guardó este token en Configuración del Repositorio -> Acciones -> Secretos bajo el nombre TOKEN_REGISTRY.
      3. Se implementó la acción oficial docker/login-action@v3 para manejar el login de forma segura.
  • Problema 7: Las imágenes subidas sobreescribían el historial (todo era latest).

    • Causa: La etiqueta latest reemplaza a la anterior sin guardar historial.
    • Solución: Implementar doble etiquetado. Subir :latest (para producción) y subir :${{ github.run_number }} (para mantener un registro de versiones atado a la ejecución del Action).

Fase 4: El Archivo Pipeline Final (ci.yml)

Este es el archivo definitivo, pulido y profesional que logró integrar todo el proceso:

name: CI/CD Pipeline

# Triggers: push to main and pull requests to main
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  # Backend build job
  backend-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup .NET 10
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: 10.x

      - name: Restore dependencies
        run: dotnet restore Backend/PruebaGentle.slnx

      - name: Build backend
        run: dotnet build Backend/PruebaGentle.slnx --configuration Release

  # Frontend build job
  frontend-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js 22
        uses: actions/setup-node@v4
        with:
          node-version: 22.x

      - name: Install dependencies
        run: npm ci
        working-directory: Frontend

      - name: Build frontend
        run: npm run build
        working-directory: Frontend

      - name: Run tests
        run: npm run test:run
        working-directory: Frontend

  docker-build:
    needs: [backend-build, frontend-build]
    runs-on: docker
    if: github.ref == 'refs/heads/main'
    env:
      DOCKER_API_VERSION: "1.41"
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Login to Gitea Registry
        uses: docker/login-action@v3
        with:
          registry: repo.eldiaservicios.com
          username: dmolinari
          password: ${{ secrets.TOKEN_REGISTRY }}

      - name: Build Docker images
        run: docker compose build

      - name: Tag versioned images
        run: |
          docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/backend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
          docker tag repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:latest repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}

      - name: Push to registry
        run: |
          docker compose push          
          docker push repo.eldiaservicios.com/dmolinari/pruebagentle/backend:${{ github.run_number }}
          docker push repo.eldiaservicios.com/dmolinari/pruebagentle/frontend:${{ github.run_number }}

      - name: Clean up old images
        run: |
          docker images --format '{{.Repository}}:{{.Tag}}' | grep 'repo.eldiaservicios.com/dmolinari/pruebagentle' | tail -n +3 | xargs -r docker rmi || true

Fase 5: Mantenimiento y Retención del Servidor

Objetivo: Evitar que el disco del servidor colapse por acumular cientos de versiones de imágenes.

  • Acción tomada: Se configuró una regla de limpieza automática desde la cuenta de Administrador del sitio de Gitea (/admin/packages).
  • Regla implementada:
    • Tipo: Container
    • Mantener el más reciente: 5 versiones por paquete (Esto actúa como escudo de seguridad mínimo).
    • Eliminar versiones anteriores a: X días (Para limpiar la basura antigua periódicamente).
  • Aclaración de Interfaz: Se aprendió que Gitea agrupa los paquetes en la vista del repositorio (hay que hacer clic para ver las versiones), mientras que en la vista de administración muestra todas las etiquetas desagrupadas.