Configuración Avanzada de Gitea y CI/CD

Gitea es una plataforma de alojamiento Git autoalojada, ligera y de código abierto que ofrece funcionalidades comparables a GitHub o GitLab con un consumo de recursos mínimo. Con Gitea Actions, webhooks y soporte LDAP, puedes construir pipelines CI/CD completos y gestionar acceso centralizado sin depender de servicios externos.

Requisitos Previos

  • Gitea instalado y funcionando (versión 1.19+)
  • Docker instalado en el servidor del runner
  • Acceso de administrador a la instancia de Gitea
  • Servidor con al menos 2 GB de RAM

Gitea Actions: Configuración del Runner

Gitea Actions es compatible con la sintaxis de GitHub Actions. Necesitas instalar un runner para ejecutar los workflows:

# Descargar act_runner (runner oficial de Gitea)
curl -s https://dl.gitea.com/act_runner/nightly/act_runner-nightly-linux-amd64 \
  -o /usr/local/bin/act_runner
chmod +x /usr/local/bin/act_runner

# Verificar la instalación
act_runner --version

Registra el runner en tu instancia de Gitea:

# Obtener el token de registro desde:
# Administración del sitio > Actions > Runners > Crear nuevo runner
# O para un runner de repositorio: Ajustes del repo > Actions > Runners

# Registrar el runner interactivamente
act_runner register

# O de forma no interactiva
act_runner register \
  --no-interactive \
  --instance https://tu-gitea.com \
  --token TU_TOKEN_DE_REGISTRO \
  --name "runner-produccion" \
  --labels "ubuntu-latest,linux,docker"

Configura el runner como servicio systemd:

sudo tee /etc/systemd/system/gitea-runner.service << 'EOF'
[Unit]
Description=Gitea Actions Runner
After=network.target docker.service

[Service]
Type=simple
User=git
WorkingDirectory=/opt/gitea-runner
ExecStart=/usr/local/bin/act_runner daemon
Restart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now gitea-runner

# Comprobar que el runner está registrado
sudo journalctl -u gitea-runner -f

Pipelines CI/CD con Gitea Actions

Crea pipelines en .gitea/workflows/ dentro de tu repositorio:

# .gitea/workflows/ci.yml
name: Pipeline CI/CD

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout del código
        uses: actions/checkout@v4

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Instalar dependencias
        run: npm ci

      - name: Ejecutar pruebas
        run: npm test

      - name: Construir imagen Docker
        run: docker build -t mi-app:${{ gitea.sha }} .

  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: gitea.ref == 'refs/heads/main'
    steps:
      - name: Desplegar en producción
        env:
          DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          echo "$DEPLOY_KEY" > /tmp/deploy_key
          chmod 600 /tmp/deploy_key
          ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no \
            deploy@$DEPLOY_HOST "cd /app && docker compose pull && docker compose up -d"

Gestión de secretos para el pipeline:

# Los secretos se configuran en:
# Repositorio > Ajustes > Actions > Secretos

# Variables de entorno disponibles en el workflow:
# ${{ secrets.NOMBRE_SECRETO }}
# ${{ vars.NOMBRE_VARIABLE }}  (variables no sensibles)

Webhooks e Integraciones

Configura webhooks para notificar servicios externos sobre eventos del repositorio:

# Webhook de Slack: ve a Ajustes del repo > Webhooks > Añadir webhook
# URL de ejemplo: https://hooks.slack.com/services/T00/B00/xxx

# Webhook personalizado con script de recepción
# En tu servidor de destino, crea un receptor:
cat > /usr/local/bin/webhook-receiver.sh << 'EOF'
#!/bin/bash
# Leer el payload del webhook
PAYLOAD=$(cat)

# Verificar la firma HMAC (seguridad)
SIGNATURE=$(echo -n "$PAYLOAD" | \
  openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | \
  awk '{print $2}')

echo "Evento recibido, ejecutando deploy..."
cd /opt/miapp && git pull && docker compose up -d --build
EOF

chmod +x /usr/local/bin/webhook-receiver.sh

Integración con Matrix o Telegram usando webhooks:

# .gitea/workflows/notify.yml
- name: Notificar por Telegram
  if: failure()
  run: |
    curl -s -X POST "https://api.telegram.org/bot${{ secrets.TG_BOT_TOKEN }}/sendMessage" \
      -d chat_id="${{ secrets.TG_CHAT_ID }}" \
      -d text="❌ Pipeline fallido en ${{ gitea.repository }} - ${{ gitea.sha }}"

Autenticación LDAP

Integra Gitea con un servidor LDAP/Active Directory:

# Ve a Administración del sitio > Fuentes de autenticación > Añadir fuente

# Configuración LDAP típica:
# Nombre: Active Directory Empresa
# Tipo: LDAP (via BindDN)
# Host: ldap.tuempresa.com
# Puerto: 389 (o 636 para LDAPS)
# DN de enlace: cn=gitea-bind,ou=ServiceAccounts,dc=empresa,dc=com
# Contraseña del DN de enlace: TU_CONTRASEÑA_LDAP
# DN raíz de usuarios: ou=Users,dc=empresa,dc=com
# Filtro de búsqueda de usuario: (&(objectClass=person)(sAMAccountName=%s))
# Atributo de nombre de usuario: sAMAccountName
# Atributo de nombre: givenName
# Atributo de apellido: sn
# Atributo de email: mail

Para configurar LDAP via la API de Gitea:

# Crear fuente de autenticación LDAP via API
curl -X POST "https://tu-gitea.com/api/v1/admin/orgs" \
  -H "Authorization: token TU_TOKEN_ADMIN" \
  -H "Content-Type: application/json" \
  -d '{
    "source_type": "ldap",
    "name": "LDAP Corporativo",
    "is_active": true,
    "cfg": {
      "host": "ldap.empresa.com",
      "port": 389,
      "bind_dn": "cn=gitea,dc=empresa,dc=com",
      "bind_password": "contraseña",
      "user_search_base": "ou=users,dc=empresa,dc=com",
      "filter": "(&(objectClass=person)(uid=%s))"
    }
  }'

Mirroring de Repositorios

Crea espejos de repositorios externos para sincronización automática:

# Via interfaz web: Explorar > + > Nueva migración > GitHub/GitLab/etc.

# Via API para crear un mirror desde GitHub
curl -X POST "https://tu-gitea.com/api/v1/repos/migrate" \
  -H "Authorization: token TU_TOKEN_ADMIN" \
  -H "Content-Type: application/json" \
  -d '{
    "clone_addr": "https://github.com/usuario/repo.git",
    "uid": 1,
    "repo_name": "repo-espejo",
    "mirror": true,
    "mirror_interval": "8h",
    "private": false
  }'

# Forzar sincronización de un mirror existente
curl -X POST "https://tu-gitea.com/api/v1/repos/usuario/repo-espejo/mirror-sync" \
  -H "Authorization: token TU_TOKEN_ADMIN"

Estrategia de Backups

Realiza backups automáticos de Gitea:

# Script de backup completo
sudo tee /usr/local/bin/gitea-backup.sh << 'EOF'
#!/bin/bash
# Variables de configuración
BACKUP_DIR="/backups/gitea"
GITEA_DIR="/opt/gitea"
DATE=$(date +%Y%m%d_%H%M%S)

# Crear directorio de backup
mkdir -p "$BACKUP_DIR"

# Detener el servicio brevemente para backup consistente
# (opcional, Gitea soporta backup en caliente)

# Ejecutar el comando de backup oficial de Gitea
gitea admin git-repositories fork-repositories \
  --config /etc/gitea/app.ini

# Backup usando el dump oficial
/usr/local/bin/gitea dump \
  --config /etc/gitea/app.ini \
  --file "$BACKUP_DIR/gitea-dump-$DATE.zip" \
  --skip-log

# Eliminar backups con más de 7 días
find "$BACKUP_DIR" -name "*.zip" -mtime +7 -delete

echo "Backup completado: gitea-dump-$DATE.zip"
EOF

chmod +x /usr/local/bin/gitea-backup.sh

# Programar backup diario con cron
echo "0 2 * * * root /usr/local/bin/gitea-backup.sh" \
  | sudo tee /etc/cron.d/gitea-backup

Solución de Problemas

El runner no se conecta a Gitea:

# Verificar conectividad desde el runner
curl -v https://tu-gitea.com/api/swagger

# Ver logs del runner
sudo journalctl -u gitea-runner -n 100 --no-pager

# Comprobar que Actions está habilitado en app.ini
grep -i actions /etc/gitea/app.ini

Pipeline falla por falta de permisos Docker:

# Añadir el usuario del runner al grupo docker
sudo usermod -aG docker git

# O configurar el runner sin Docker (modo proceso)
# En la configuración del runner, usar: labels: "native"

LDAP no autentica usuarios:

# Probar la conexión LDAP manualmente
ldapsearch -x -H ldap://ldap.empresa.com \
  -D "cn=gitea-bind,dc=empresa,dc=com" \
  -W -b "ou=Users,dc=empresa,dc=com" "(sAMAccountName=usuario_prueba)"

Conclusión

Gitea con Actions y runners proporciona una plataforma CI/CD completa y autoalojada que cubre desde el control de versiones hasta el despliegue automatizado. La integración LDAP y el mirroring de repositorios hacen de Gitea una solución empresarial capaz de satisfacer las necesidades de equipos de cualquier tamaño sin costes de licencias. Combina backups automáticos con una política de retención adecuada para garantizar la continuidad del negocio.