167 lines
7.6 KiB
Markdown
167 lines
7.6 KiB
Markdown
# 📖 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):**
|
|
```yaml
|
|
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:
|
|
|
|
```yaml
|
|
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.
|
|
|
|
--- |