--- title: "Gitea Actions: runner CI/CD, LDAP, mirrors y backups" description: "Configura Gitea Actions con act_runner en Ubuntu 24.04, crea un pipeline CI/CD, conecta LDAP, replica repositorios externos y automatiza copias con gitea dump." category: "Herramientas de Desarrollo" language: es source: https://cubepath.com/es/docs/herramientas-de-desarrollo/configuracion-avanzada-de-gitea-y-ci-cd updated: 2026-09-25 --- # Gitea Actions: runner CI/CD, LDAP, mirrors y backups Gitea es una plataforma Git autoalojada y ligera con incidencias, pull requests y un sistema de CI/CD integrado, Gitea Actions, compatible con la sintaxis de GitHub Actions. En este tutorial partirás de una instalación de Gitea ya funcionando en Ubuntu 24.04 y añadirás lo que la convierte en una plataforma de equipo: un runner `act_runner` para ejecutar pipelines en contenedores Docker, un workflow de ejemplo, autenticación LDAP, repositorios espejo y copias de seguridad diarias automatizadas. ## Requisitos previos Para seguir esta guía necesitas: - Gitea 1.21 o posterior instalado con el binario oficial en Ubuntu 24.04, con la disposición de la documentación de Gitea: binario en `/usr/local/bin/gitea`, configuración en `/etc/gitea/app.ini`, datos en `/var/lib/gitea` y usuario del sistema `git`. Si usas otras rutas, adáptalas en los comandos. - Gitea publicado con HTTPS en un dominio, en la guía `git.your_domain`. - Una cuenta de administrador en Gitea. - Docker Engine instalado en la máquina del runner (puede ser el mismo servidor, por ejemplo un VPS de CubePath con al menos 4 GB de RAM, o uno dedicado a CI). - Un usuario no root con privilegios `sudo`. ## Paso 1: Comprobar que Gitea Actions está activado Desde Gitea 1.21, Actions está activado por defecto. Comprueba que no se ha desactivado en la configuración: ```bash sudo grep -A2 '^\[actions\]' /etc/gitea/app.ini ``` Si el comando no devuelve nada, se usa el valor por defecto y Actions está activo. Si ves `ENABLED = false`, cámbialo a `true` y reinicia Gitea con `sudo systemctl restart gitea`. Para confirmarlo en la interfaz, entra como administrador en **Administración del sitio**: debe aparecer la sección **Actions > Runners**. ## Paso 2: Instalar act_runner `act_runner` es el runner oficial de Gitea. Recibe trabajos de la instancia y los ejecuta en contenedores Docker. Consulta la última versión estable en `https://dl.gitea.com/act_runner/` y guárdala en una variable: ```bash RUNNER_VERSION=0.2.13 ``` Descarga el binario para tu arquitectura (`amd64` o `arm64`) e instálalo: ```bash curl -fL -o act_runner "https://dl.gitea.com/act_runner/${RUNNER_VERSION}/act_runner-${RUNNER_VERSION}-linux-amd64" sudo install -m 0755 act_runner /usr/local/bin/act_runner act_runner --version ``` ```output act_runner version v0.2.13 ``` Crea un usuario de sistema propio para el runner y añádelo al grupo `docker`, ya que lanzará contenedores: ```bash sudo useradd --system --create-home --home-dir /var/lib/act_runner --shell /usr/sbin/nologin act_runner sudo usermod -aG docker act_runner ``` > Advertencia: pertenecer al grupo `docker` equivale en la práctica a tener acceso root en la máquina. Por eso el runner tiene su propio usuario y conviene usarlo solo con repositorios de confianza. Genera la configuración por defecto en `/etc/act_runner`: ```bash sudo mkdir -p /etc/act_runner act_runner generate-config | sudo tee /etc/act_runner/config.yaml > /dev/null ``` El fichero generado está comentado. Los valores por defecto sirven para empezar; el más relevante es `runner.capacity`, el número de trabajos simultáneos (1 por defecto). ## Paso 3: Registrar el runner En Gitea, ve a **Administración del sitio > Actions > Runners > Crear nuevo runner** y copia el token de registro. Un runner registrado ahí sirve a toda la instancia; si prefieres uno por organización o repositorio, obtén el token en sus ajustes de Actions. Registra el runner como el usuario `act_runner` y desde su directorio de trabajo, porque el registro crea ahí el fichero `.runner` con sus credenciales. Sustituye `your_registration_token`: ```bash sudo -u act_runner sh -c 'cd /var/lib/act_runner && act_runner register \ --no-interactive \ --config /etc/act_runner/config.yaml \ --instance https://git.your_domain \ --token your_registration_token \ --name runner-01 \ --labels ubuntu-latest:docker://gitea/runner-images:ubuntu-latest' ``` ```output INFO Registering runner, arch=amd64, os=linux, version=v0.2.13. INFO Runner registered successfully. ``` La etiqueta `ubuntu-latest:docker://gitea/runner-images:ubuntu-latest` significa que los trabajos con `runs-on: ubuntu-latest` se ejecutarán en un contenedor de esa imagen, que incluye Node.js y las herramientas habituales de las acciones de GitHub. ## Paso 4: Ejecutar el runner como servicio Crea la unidad de systemd: ```bash sudo nano /etc/systemd/system/act_runner.service ``` ```ini [Unit] Description=Gitea Actions runner Documentation=https://gitea.com/gitea/act_runner After=docker.service Requires=docker.service [Service] ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml ExecReload=/bin/kill -s HUP $MAINPID WorkingDirectory=/var/lib/act_runner User=act_runner Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` Actívala y revisa el registro: ```bash sudo systemctl daemon-reload sudo systemctl enable --now act_runner sudo journalctl -u act_runner -n 10 --no-pager ``` ```output INFO Starting runner daemon INFO runner: runner-01, with version: v0.2.13, with labels: [ubuntu-latest], declare successfully ``` En **Administración del sitio > Actions > Runners**, `runner-01` debe aparecer con estado **Idle**. ## Paso 5: Crear un pipeline CI/CD Los workflows se guardan en `.gitea/workflows/` dentro del repositorio. Si el repositorio es nuevo, activa Actions en **Ajustes del repositorio > Unidades > Actions**. Este ejemplo para un proyecto Node.js ejecuta las pruebas en cada push y pull request, y despliega por SSH solo cuando el push llega a `main`: ```yaml name: CI on: push: branches: [main] pull_request: jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '22' - run: npm ci - run: npm test deploy: needs: test if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: - name: Desplegar por SSH env: DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} run: | install -m 700 -d ~/.ssh echo "$DEPLOY_KEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts ssh deploy@"$DEPLOY_HOST" 'cd /srv/app && git pull && docker compose up -d --build' ``` Guárdalo como `.gitea/workflows/ci.yml`. Gitea descarga `actions/checkout` y `actions/setup-node` desde GitHub por defecto, así que el runner necesita salida a Internet. Crea los secretos `DEPLOY_HOST` (IP o nombre del servidor de destino) y `DEPLOY_KEY` (clave privada SSH de un usuario `deploy` con acceso limitado) en **Ajustes del repositorio > Actions > Secretos**. Los secretos no se muestran en los registros de los trabajos. Haz commit y push, y abre la pestaña **Actions** del repositorio. Verás la ejecución con sus dos trabajos; un círculo verde en cada uno indica que terminó correctamente. ## Paso 6: Notificar eventos con webhooks Los webhooks avisan a servicios externos (Slack, Discord, Matrix, Telegram o una URL propia) cuando ocurre algo en el repositorio. Gitea incluye formatos nativos para los principales servicios de chat, así que no necesitas scripts intermedios. Ve a **Ajustes del repositorio > Webhooks > Añadir webhook**, elige el tipo (por ejemplo **Discord** o **Slack**), pega la URL de entrada que te da ese servicio y selecciona los eventos, como **Push** o **Pull request**. Para un webhook de tipo **Gitea** hacia tu propia aplicación, rellena también **Secreto**: Gitea firmará cada petición con HMAC-SHA256 en la cabecera `X-Gitea-Signature`, que tu aplicación debe verificar. Tras guardarlo, pulsa **Probar entrega**. En **Entregas recientes** verás la petición enviada y el código de respuesta; un `200` o `204` confirma que llega. ## Paso 7: Conectar Gitea con LDAP o Active Directory Con LDAP, los usuarios inician sesión en Gitea con sus credenciales corporativas y la cuenta se crea en el primer acceso. Antes de configurar Gitea, comprueba desde el servidor que la cuenta de servicio puede buscar usuarios. Instala el cliente y lanza una búsqueda de prueba (te pedirá la contraseña de la cuenta de enlace): ```bash sudo apt install ldap-utils ldapsearch -x -H ldaps://ldap.your_domain -D "cn=gitea-bind,ou=Servicios,dc=example,dc=com" -W -b "ou=Usuarios,dc=example,dc=com" "(sAMAccountName=usuario_prueba)" mail ``` Si devuelve el usuario con su atributo `mail`, añade la fuente de autenticación con la CLI de Gitea, ejecutada como el usuario `git`. Este ejemplo es para Active Directory por LDAPS; en OpenLDAP usa `uid` en lugar de `sAMAccountName`: ```bash sudo -u git gitea admin auth add-ldap \ --config /etc/gitea/app.ini \ --work-path /var/lib/gitea \ --name "Active Directory" \ --security-protocol LDAPS \ --host ldap.your_domain \ --port 636 \ --bind-dn "cn=gitea-bind,ou=Servicios,dc=example,dc=com" \ --bind-password 'your_bind_password' \ --user-search-base "ou=Usuarios,dc=example,dc=com" \ --user-filter "(&(objectClass=user)(sAMAccountName=%s))" \ --username-attribute sAMAccountName \ --firstname-attribute givenName \ --surname-attribute sn \ --email-attribute mail ``` Comprueba que la fuente existe: ```bash sudo -u git gitea admin auth list --config /etc/gitea/app.ini --work-path /var/lib/gitea ``` ```output ID Name Type Enabled 1 Active Directory LDAP (via BindDN) true ``` Cierra sesión e inicia sesión con un usuario del directorio. La fuente se puede editar después en **Administración del sitio > Fuentes de autenticación**. ## Paso 8: Crear repositorios espejo Un espejo (mirror) es una copia de solo lectura de un repositorio externo que Gitea sincroniza periódicamente. Es útil para tener una copia local de dependencias o de proyectos alojados en GitHub. Desde la interfaz, usa **+ > Nueva migración**, elige el origen y marca **Este repositorio será un espejo**. Para automatizarlo, usa la API. Crea antes un token de acceso en **Configuración > Aplicaciones** con permiso de escritura sobre repositorios y sustituye `your_api_token` y `your_user`: ```bash curl -fsS -X POST "https://git.your_domain/api/v1/repos/migrate" \ -H "Authorization: token your_api_token" \ -H "Content-Type: application/json" \ -d '{ "clone_addr": "https://github.com/go-gitea/gitea.git", "repo_name": "gitea-mirror", "repo_owner": "your_user", "mirror": true, "mirror_interval": "8h0m0s", "private": true }' ``` La respuesta es el JSON del repositorio creado con `"mirror": true`. Para forzar una sincronización sin esperar al intervalo: ```bash curl -fsS -X POST "https://git.your_domain/api/v1/repos/your_user/gitea-mirror/mirror-sync" \ -H "Authorization: token your_api_token" ``` ## Paso 9: Automatizar copias de seguridad con gitea dump `gitea dump` genera un único fichero con los repositorios, la base de datos exportada, la configuración y los datos adjuntos. Crea un directorio para las copias, propiedad del usuario `git`: ```bash sudo install -d -o git -g git -m 750 /var/backups/gitea ``` Crea el script de copia: ```bash sudo nano /usr/local/bin/gitea-backup ``` ```bash #!/usr/bin/env bash set -euo pipefail BACKUP_DIR="/var/backups/gitea" KEEP_DAYS=7 STAMP="$(date +%Y%m%d-%H%M%S)" cd "$BACKUP_DIR" /usr/local/bin/gitea dump \ --config /etc/gitea/app.ini \ --work-path /var/lib/gitea \ --tempdir "$BACKUP_DIR" \ --skip-log \ --file "$BACKUP_DIR/gitea-dump-$STAMP.zip" find "$BACKUP_DIR" -maxdepth 1 -name 'gitea-dump-*.zip' -mtime +"$KEEP_DAYS" -delete ``` Hazlo ejecutable y pruébalo como el usuario `git`: ```bash sudo chmod 755 /usr/local/bin/gitea-backup sudo -u git /usr/local/bin/gitea-backup sudo ls -lh /var/backups/gitea ``` ```output -rw------- 1 git git 148M Sep 25 12:40 gitea-dump-20260925-124002.zip ``` Prográmalo cada noche con un temporizador de systemd. Primero el servicio: ```bash sudo nano /etc/systemd/system/gitea-backup.service ``` ```ini [Unit] Description=Copia de seguridad de Gitea [Service] Type=oneshot User=git ExecStart=/usr/local/bin/gitea-backup ``` Después el temporizador: ```bash sudo nano /etc/systemd/system/gitea-backup.timer ``` ```ini [Unit] Description=Copia diaria de Gitea [Timer] OnCalendar=*-*-* 03:00:00 Persistent=true [Install] WantedBy=timers.target ``` Actívalo y comprueba la próxima ejecución: ```bash sudo systemctl daemon-reload sudo systemctl enable --now gitea-backup.timer systemctl list-timers gitea-backup.timer ``` > Importante: una copia en el mismo disco no protege frente a la pérdida del servidor. Copia los ficheros de `/var/backups/gitea` a otro sistema o a almacenamiento de objetos. ## Solución de problemas **El runner aparece como Offline.** Revisa `sudo journalctl -u act_runner -n 50 --no-pager`. Si ves errores de conexión, comprueba desde la máquina del runner que la URL responde con `curl -I https://git.your_domain`. Si el error es de permisos sobre `/var/run/docker.sock`, confirma que `act_runner` está en el grupo `docker` y reinicia el servicio. **Los trabajos quedan en espera ("Waiting").** Ningún runner tiene la etiqueta del `runs-on`. Compara las etiquetas del runner en la lista de runners con las del workflow. **Los usuarios LDAP no pueden iniciar sesión.** Repite la búsqueda con `ldapsearch` sustituyendo `%s` por el usuario real. Si falla con LDAPS, comprueba que el servidor confía en el certificado del controlador de dominio. **`gitea dump` falla por permisos.** Ejecútalo siempre como `git`; con otro usuario no puede leer `/var/lib/gitea` ni `/etc/gitea/app.ini`. ## Conclusión Tu instancia de Gitea ya ejecuta pipelines CI/CD con un runner propio en Docker, autentica contra el directorio corporativo, mantiene espejos de repositorios externos y guarda una copia diaria con rotación de 7 días. Como siguientes pasos, puedes añadir más runners con etiquetas distintas (por ejemplo `arm64`), activar el registro de paquetes y contenedores integrado de Gitea para publicar artefactos desde los workflows y practicar la restauración de una copia en un servidor de pruebas.