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.


