TL;DR — Resumen Rápido

Despliega Gitea como forge Git autoalojado. Cubre Docker Compose, systemd, Gitea Actions, LDAP, OAuth2, registros de paquetes, mirroring y proxy inverso Caddy.

Gitea es un forge Git ligero y autoalojado escrito en Go que se distribuye como un binario único y funciona cómodamente en hardware tan modesto como una Raspberry Pi. Si alguna vez has querido control total sobre tu código fuente, pipelines de CI/CD, seguimiento de incidencias y registros de paquetes sin pagar precios de GitHub o GitLab en la nube — y sin el peso operativo de una instancia de GitLab CE — Gitea es la respuesta. Esta guía cubre desde un despliegue de producción con Docker Compose hasta Gitea Actions CI, SSO con OAuth2, registros de paquetes y mirroring de repositorios.

Requisitos Previos

  • Docker y Docker Compose v2 instalados en el host
  • Un nombre de dominio apuntando al servidor (para TLS con Caddy)
  • Al menos 512 MB de RAM y 2 GB de disco (Gitea necesita ~150 MB; el resto para PostgreSQL y repositorios)
  • Familiaridad básica con volúmenes Docker y sintaxis YAML
  • Puerto 3000 (o 80/443 mediante proxy inverso) accesible desde tu red

Arquitectura de Gitea

Gitea es una aplicación Go compilada en un único binario sin dependencias en tiempo de ejecución. Incluye un servidor web, hooks de Git, un daemon SSH y trabajadores en segundo plano. Opciones de almacenamiento:

BackendIdeal paraNotas
SQLiteUsuario único / equipos pequeñosSin configuración; no apto para alta concurrencia
PostgreSQLEquipos y producciónRecomendado; mejor rendimiento
MySQL / MariaDBInfraestructura MySQL existenteSoportado; se prefiere PostgreSQL

Los datos de repositorios se almacenan como repos Git bare en disco bajo $GITEA_WORK_DIR/repositories. Los objetos LFS van a $GITEA_WORK_DIR/lfs. Los adjuntos, avatares y paquetes usan $GITEA_WORK_DIR/data.

Gitea vs Forgejo vs Alternativas

ForgeLenguajeRAM (reposo)Actions CIRegistro de paquetesLicencia
GiteaGo~120 MBSí (act_runner)Sí (11 tipos)MIT
ForgejoGo~120 MBSí (act_runner)MIT
GitLab CERuby/Go~2–4 GBSí (nativo)MIT
GogsGo~50 MBNoNoMIT
OneDevJava~500 MBLimitadoMIT
SourcehutPython/Go~100 MBSí (builds.sr.ht)NoAGPL

Forgejo es compatible en API con Gitea y los runners son intercambiables. La migración entre ambos es sencilla. GitLab CE es mucho más completo en funcionalidades, pero requiere entre 10 y 20 veces más recursos.


Paso 1: Desplegar con Docker Compose y PostgreSQL

Crea un directorio de proyecto y un docker-compose.yml:

services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: unless-stopped
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=postgres
      - GITEA__database__HOST=db:5432
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=changeme
    volumes:
      - gitea-data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: gitea-db
    restart: unless-stopped
    environment:
      - POSTGRES_USER=gitea
      - POSTGRES_PASSWORD=changeme
      - POSTGRES_DB=gitea
    volumes:
      - postgres-data:/var/lib/postgresql/data

volumes:
  gitea-data:
  postgres-data:
docker compose up -d

Abre http://tu-servidor:3000 en un navegador. El instalador web rellena previamente la configuración de la base de datos desde las variables de entorno. Solo configura la URL base, el nombre de usuario administrador, el correo del administrador y la contraseña de administrador, luego haz clic en Instalar. Gitea inicializa el esquema de la base de datos y te redirige al panel en segundos.


Paso 2: Configurar app.ini

Tras la ejecución del instalador, app.ini se encuentra en el volumen Docker bajo gitea/conf/app.ini. Edítalo para reforzar la configuración:

[server]
DOMAIN           = git.ejemplo.com
ROOT_URL         = https://git.ejemplo.com/
HTTP_PORT        = 3000
SSH_DOMAIN       = git.ejemplo.com
SSH_PORT         = 22
SSH_LISTEN_PORT  = 22
DISABLE_SSH      = false
LFS_START_SERVER = true

[repository]
DEFAULT_BRANCH          = main
ENABLE_PUSH_CREATE_USER = false
DEFAULT_PRIVATE         = private

[security]
INSTALL_LOCK              = true
SECRET_KEY                = <genera-con-openssl-rand-hex-32>
INTERNAL_TOKEN            = <genera-con-gitea-generate-secret>
MIN_PASSWORD_LENGTH       = 12
PASSWORD_COMPLEXITY       = lower,upper,digit,spec

[service]
DISABLE_REGISTRATION              = false
REQUIRE_SIGNIN_VIEW               = false
REGISTER_EMAIL_CONFIRM            = true
ENABLE_NOTIFY_MAIL                = true
ALLOW_ONLY_EXTERNAL_REGISTRATION  = false

[mailer]
ENABLED   = true
SMTP_ADDR = smtp.ejemplo.com
SMTP_PORT = 587
FROM      = "Gitea <gitea@ejemplo.com>"
USER      = gitea@ejemplo.com
PASSWD    = `tu-contraseña-smtp`

Reinicia para aplicar los cambios:

docker compose restart gitea

Paso 3: Gestión de Repositorios

Git LFS

LFS se habilita con LFS_START_SERVER = true en [server]. Los usuarios configuran su cliente local una vez:

git lfs install
git lfs track "*.psd" "*.zip" "*.tar.gz"

Gitea almacena los objetos LFS en $GITEA_WORK_DIR/data/lfs. Haz una copia de seguridad de este directorio por separado de la base de datos.

Mirroring de Repositorios

Los mirrors pull permiten a Gitea clonar y sincronizar periódicamente desde GitHub, GitLab o cualquier remoto Git. En la interfaz web: Nuevo Repositorio → Migrar. Selecciona la fuente y marca Este repositorio será un mirror con el intervalo de sincronización deseado.

Los mirrors push envían cada commit a un remoto automáticamente. Configúralos en Configuración del repositorio → Configuración de mirrors → Push Mirrors.

Ramas Protegidas y Estrategias de Fusión

En Configuración del repositorio → Ramas → Añadir regla de protección de rama:

  • Requerir revisiones de pull request — establece aprobaciones mínimas
  • Requerir comprobaciones de estado — bloquea la fusión si falla el flujo de trabajo de Actions
  • Restringir push — lista blanca de equipos o usuarios
  • Estrategias de fusión — habilita/deshabilita commit de fusión, squash y rebase por repositorio

Paso 4: Gitea Actions CI

Gitea Actions es el sistema de CI integrado que usa la misma sintaxis YAML que GitHub Actions.

Registrar un act_runner

Descarga el último binario act_runner desde https://gitea.com/gitea/act_runner/releases. En el panel de administración ve a Administración del sitio → Actions → Runners → Crear nuevo token de runner.

# Registrar el runner
act_runner register \
  --instance https://git.ejemplo.com \
  --token <token-runner> \
  --name mi-runner \
  --labels ubuntu-latest:docker://node:20-bullseye

# Iniciar como servicio
act_runner daemon

Ejemplo de Flujo de Trabajo

# .gitea/workflows/build.yml
name: Compilar y Probar

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: "20"
          cache: "npm"
      - run: npm ci
      - run: npm test

  docker:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Construir imagen Docker
        run: docker build -t miapp:${{ gitea.sha }} .
      - name: Publicar en registro de Gitea
        run: |
          docker login git.ejemplo.com -u ${{ secrets.REGISTRY_USER }} -p ${{ secrets.REGISTRY_TOKEN }}
          docker push git.ejemplo.com/miorg/miapp:${{ gitea.sha }}

La mayoría de las acciones del marketplace de GitHub funcionan en Gitea Actions porque act_runner usa el mismo protocolo de runner. Las acciones que referencian variables de contexto github.com necesitan ajustes mínimos (github.*gitea.*).


Paso 5: Gestión de Usuarios y Autenticación

Cuentas Locales y 2FA

Los usuarios se autoregistran (o los administradores crean cuentas). 2FA mediante TOTP disponible en Configuración de usuario → Seguridad → Autenticación de dos factores. Los administradores del sitio pueden obligar al 2FA en toda la organización desde el panel de administración.

LDAP / Active Directory

Administración del sitio → Identidad y acceso → Fuentes de autenticación → LDAP (via BindDN):

  • Host: ldap.ejemplo.com
  • Puerto: 389 (o 636 para LDAPS)
  • Bind DN: cn=gitea,ou=cuentas-servicio,dc=ejemplo,dc=com
  • Base de búsqueda de usuarios: ou=usuarios,dc=ejemplo,dc=com
  • Filtro de usuario: (&(objectClass=person)(sAMAccountName=%s))
  • Atributo de correo: mail

Proveedores OAuth2

Añade inicio de sesión con GitHub, GitLab o Google en Fuentes de autenticación → OAuth2:

ProveedorOrigen del Client IDAlcance
GitHubgithub.com/settings/developersread:user,user:email
GitLabgitlab.com/-/profile/applicationsread_user
Googleconsole.cloud.google.comopenid email profile

Los usuarios pueden vincular cuentas OAuth2 externas a cuentas locales existentes desde Configuración de usuario → Seguridad → Cuentas vinculadas.


Paso 6: Proxy Inverso Caddy con TLS

Añade esto a tu Caddyfile:

git.ejemplo.com {
    reverse_proxy gitea:3000

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
    }
}

Caddy obtiene certificados de Let’s Encrypt automáticamente en la primera solicitud al dominio.


Organizaciones, Equipos y Permisos

El modelo de permisos de Gitea es similar al de GitHub:

RolRepositoriosPanel de adminCrear repos
PropietarioTodos en la org
Admin (equipo)Repos del equipoNoAlcance del equipo
Escritura (equipo)Repos del equipoNoNo
Lectura (equipo)Repos del equipoNoNo

Registro de Paquetes de Gitea

Habilita el registro de paquetes en app.ini:

[packages]
ENABLED = true

Tipos de paquetes soportados: npm, PyPI, Maven, NuGet, Docker/OCI, Composer, Cargo, Conan, Helm, RubyGems y APT Alpine/Debian.

Ejemplo npm

npm config set registry https://git.ejemplo.com/api/packages/miorg/npm/
npm config set //git.ejemplo.com/api/packages/miorg/npm/:_authToken <token>
npm publish

Webhooks y API REST

La API REST v1 de Gitea está documentada en https://git.ejemplo.com/api/swagger. Cada recurso tiene endpoints CRUD completos compatibles con la forma de la API de GitHub/Gitea.

Copia de Seguridad y Restauración

# Dentro del contenedor
docker exec -u git gitea gitea dump -c /data/gitea/conf/app.ini \
  -t /tmp --type tar.gz

# Copiar el archivo al exterior
docker cp gitea:/tmp/gitea-dump-*.tar.gz ./copias-seguridad/

Migración desde GitHub, GitLab o Gogs

Administración del sitio → Migraciones soporta importación completa preservando:

  • Incidencias y comentarios
  • Pull requests
  • Etiquetas e hitos
  • Lanzamientos y activos de lanzamientos
  • Páginas wiki

La migración de Gogs a Gitea es transparente: Gitea lee directamente la base de datos de Gogs y migra el esquema automáticamente.

Errores Comunes y Casos Especiales

Conflicto de puerto SSH — Si el puerto 22 ya lo usa el daemon SSH del host, mapea el SSH de Gitea a un puerto diferente (p. ej., 222:22) y actualiza SSH_PORT en app.ini.

Docker-in-Docker con act_runner — Para flujos de trabajo que construyen imágenes Docker, el runner necesita acceso al socket de Docker. Monta /var/run/docker.sock en el contenedor del runner.

Crecimiento del almacenamiento LFS — Los objetos LFS no se recogen automáticamente. Programa gitea admin repo-lfs-prune periódicamente.

Solución de Problemas

ProblemaSolución
La interfaz web devuelve 502Comprueba docker logs gitea; verifica las variables de entorno de conexión a la BD
El clon por SSH fallaConfirma que SSH_PORT coincide con el mapeo de puertos del host
Flujo de Actions en cola para siempreVerifica que act_runner esté en ejecución y registrado; comprueba que las etiquetas del runner coincidan
Push de paquete con error 401Genera un token con alcance package; úsalo como contraseña del registro
El mirror no sincronizaVerifica que la URL del mirror sea accesible desde el contenedor

Resumen

  • Gitea funciona con ~120 MB de RAM como binario Go único — mucho más ligero que GitLab CE
  • Docker Compose con PostgreSQL es el despliegue de producción recomendado
  • app.ini controla cada aspecto: seguridad, mailer, LFS, paquetes y SSH
  • Gitea Actions usa la sintaxis YAML de GitHub Actions; act_runner ejecuta trabajos en contenedores Docker
  • LDAP, OAuth2 (GitHub/GitLab/Google) y TOTP 2FA están integrados
  • Los registros de paquetes soportan npm, PyPI, Maven, NuGet, Docker/OCI y más
  • El mirroring de repositorios (push y pull) mantiene los repos externos sincronizados automáticamente

Artículos Relacionados