Índice del diarioDockup / nota de campo
Note / self-host-gitea

Cómo alojar Gitea por cuenta propia en 2026: repositorios, SSH y actualizaciones seguras

Implementa Gitea con el puerto adecuado, almacenamiento persistente, TLS, autenticación y copias de seguridad. Soluciona los casos en los que ROOT_URL genera enlaces de clonación con localhost en producción.

Si ya has intentado alojar Gitea por cuenta propia, probablemente conozcas bien esta situación frustrante: la interfaz aparece, pero ROOT_URL genera enlaces de clonación con localhost o el puerto SSH no está redirigido. Recrear el contenedor rara vez resuelve un desacuerdo entre las URL, el estado y las dependencias.

Este recorrido utiliza un único criterio concreto de finalización: clonar mediante HTTPS y SSH, hacer push de un commit y un objeto LFS, abrir una incidencia y ejecutar un job en un runner de Actions registrado por separado. Cada decisión de configuración se evalúa según ese criterio, no según que el indicador del contenedor aparezca en verde.

Encuentra cada byte persistente de Gitea

Enumera el estado antes de crear el primer registro real: repositorios, objetos LFS, archivos adjuntos, configuración y base de datos. Monta /data antes del bootstrap, escribe datos de muestra inocuos y sustituye el contenedor para demostrar que esa ruta es realmente persistente. Confirma el montaje escribiendo datos inocuos, sustituyendo Gitea y leyéndolos de nuevo.

Las instantáneas son útiles para volver atrás rápidamente, pero necesitas una copia de seguridad independiente si el host o el volumen desaparecen. Restaura en un entorno vacío con la imagen fijada y verifica que los repositorios superan fsck, que los objetos LFS se descargan y que las incidencias, releases y permisos de usuario coinciden con el estado anterior a la copia de seguridad. Usa volúmenes persistentes e instantáneas para mantener diferenciados estos dos mecanismos de recuperación.

Crea un contenedor de Gitea reemplazable

El siguiente comando hace visible el límite del contenedor sin pretender aprovisionar todos los servicios externos.

docker run -d \
  --name gitea \
  --restart unless-stopped \
  -p 127.0.0.1:3000:3000 \
  -v gitea-data:/data \
  -e GITEA__security__SECRET_KEY=replace-with-a-long-random-value \
  gitea/gitea:latest

Antes de abrir el ingress, inspecciona el entorno resuelto, los montajes y el listener. Añade la configuración de conexión revisada para Postgres o MySQL en instalaciones con mayor carga, así como una ruta SSH si es necesario; utiliza nombres privados para los servicios privados. Un arranque correcto termina cuando puedes clonar mediante HTTPS y SSH, hacer push de un commit y un objeto LFS, abrir una incidencia y ejecutar un job en un runner de Actions registrado por separado, no cuando docker ps muestra Up.

Separa Gitea de sus dependencias

En Gitea, la salud del proceso y la salud del producto son aspectos distintos. El puerto 3000 puede responder aunque la transacción que realiza el usuario siga fallando. El contrato de red de Gitea incluye Postgres o MySQL en instalaciones con mayor carga y una ruta SSH si es necesario. Mantén los endpoints privados en el DNS interno, permite únicamente las llamadas salientes necesarias y proporciona a Gitea una credencial de servicio con permisos limitados.

Utiliza este ejercicio de readiness después de cambios de configuración relevantes: clona mediante HTTPS y SSH, haz push de un commit y un objeto LFS, abre una incidencia y ejecuta un job en un runner de Actions registrado por separado. Mantén las comprobaciones externas costosas fuera de las sondas de liveness para que una interrupción del proveedor no provoque un bucle de reinicios. El trabajo de capacidad debe seguir el número de repositorios, el empaquetado de objetos de Git, el almacenamiento LFS, la latencia de la base de datos y la carga de los runners, en lugar de las solicitudes de páginas habituales, ya que esto refleja mejor la presión real sobre Gitea.

TLS es fácil; las URL generadas, no

Expón un único hostname HTTPS para Gitea y mantén privado el puerto 3000 sin procesar. Configura ROOT_URL y SSH_DOMAIN con las direcciones desde las que los usuarios realmente clonan. Así evitarás que los navegadores y los clientes de API conozcan dos direcciones distintas que compiten entre sí.

Desde un cliente limpio, ejecuta la transacción conocida como correcta e inspecciona la primera solicitud que falle. Usa la guía de dominios personalizados cuando el problema esté en el DNS o TLS. Trata “ROOT_URL genera enlaces de clonación con localhost o el puerto SSH no está redirigido” como un diagnóstico independiente de la aplicación una vez confirmada la ruta.

Valida la implementación de Gitea de extremo a extremo

No utilices el tráfico del primer usuario como prueba de aceptación de Gitea. Prepara un estado de muestra inocuo y ejecuta la acción completa “clonar mediante HTTPS y SSH, hacer push de un commit y un objeto LFS, abrir una incidencia y ejecutar un job en un runner de Actions registrado por separado”. Anota la URL pública exacta, el resultado, la referencia de la imagen y el intervalo de logs asociados a la ejecución.

Sustituye el contenedor y repite el proceso sin reconstruir los datos. A continuación, recupera el servicio en un host vacío; la condición de recuperación es que los repositorios superen fsck, los objetos LFS se descarguen y las incidencias, releases y permisos de usuario coincidan con el estado anterior a la copia de seguridad. En cada pasada, observa el número de repositorios, el empaquetado de objetos de Git, el almacenamiento LFS, la latencia de la base de datos y la carga de los runners, en lugar de las solicitudes de páginas habituales, y define una alerta en torno a la degradación de la transacción, no en torno a las métricas de un contenedor inactivo.

Una última comprobación debe fallar deliberadamente: deniega temporalmente a la identidad de prueba el acceso a Postgres o MySQL en instalaciones con mayor carga y a una ruta SSH si es necesario. Verifica que el mensaje resultante de Gitea identifica el límite relevante en lugar de activar el borrado de datos o un reinicio interminable. Restablece la condición válida y confirma que la misma transacción de muestra vuelve a completarse correctamente. Incluye este breve ejercicio en la checklist de releases.

Ensaya el cambio de Gitea más arriesgado

En Gitea, supervisa una transacción en lugar de un proceso: clona mediante HTTPS y SSH, haz push de un commit y un objeto LFS, abre una incidencia y ejecuta un job en un runner de Actions registrado por separado. Combina su latencia y tasa de errores con el número de repositorios, el empaquetado de objetos de Git, el almacenamiento LFS, la latencia de la base de datos y la carga de los runners, en lugar de las solicitudes de páginas habituales, para que una alerta identifique el componente limitado.

El ensayo de actualización debe contemplar que las migraciones de esquema, los hooks de los repositorios, los paquetes y los runners de terceros requieren una actualización de Gitea por fases. Restaura, migra y ejecuta la transacción antes de sustituir la versión en producción. Si ROOT_URL genera enlaces de clonación con localhost o el puerto SSH no está redirigido, no borres datos para que el arranque aparezca en verde; compara la versión, las variables, los montajes y la accesibilidad de las dependencias, en ese orden.

Protege la parte valiosa de Gitea

Después del primer inicio de sesión, revisa qué puede hacer un visitante anónimo, un usuario normal y un administrador. El fallo de Gitea que debes evitar es mantener accesibles el instalador o la primera cuenta de administrador durante más tiempo del necesario. La política prevista consiste en cerrar el instalador después del bootstrap, restringir la administración del sitio y mantener los tokens de registro de runners con una vida útil corta.

Trata GITEA__security__SECRET_KEY según su función en Gitea: mantén los valores sensibles fuera de Git, documenta los efectos de la rotación y no sustituyas nunca un ejemplo público en producción. Mantén separadas las cuentas de dependencias de las cuentas humanas, deniega el egress que no se utilice cuando sea viable y limita el trabajo influido por el número de repositorios, el empaquetado de objetos de Git, el almacenamiento LFS, la latencia de la base de datos y la carga de los runners, en lugar de las solicitudes de páginas habituales.

Qué debería automatizar Dockup para Gitea

Para Gitea, Dockup puede crear la ruta y el certificado TLS, conservar los montajes, entregar los secretos y situar Postgres o MySQL en instalaciones con mayor carga, así como una ruta SSH si es necesario, en una red privada mientras realiza el despliegue en Dockup o en servidores conectados.

El gate de release sigue siendo la transacción concreta de Gitea: clonar mediante HTTPS y SSH, hacer push de un commit y un objeto LFS, abrir una incidencia y ejecutar un job en un runner de Actions registrado por separado. Verifica también la condición de restauración: los repositorios superan fsck, los objetos LFS se descargan y las incidencias, releases y permisos de usuario coinciden con el estado anterior a la copia de seguridad. Estas dos comprobaciones muestran si la implementación funciona y si puede recuperarse.

Preguntas frecuentes

¿Qué necesita Gitea para una implementación en producción?

Enruta el contenedor de Gitea en el puerto 3000 a través de un único origen HTTPS. El requisito de red de soporte incluye Postgres o MySQL en instalaciones con mayor carga y una ruta SSH si es necesario. No consideres Gitea listo hasta que puedas clonar mediante HTTPS y SSH, hacer push de un commit y un objeto LFS, abrir una incidencia y ejecutar un job en un runner de Actions registrado por separado.

¿Qué datos de Gitea deben incluirse en una copia de seguridad?

Haz persistir /data e incluye los repositorios, los objetos LFS, los archivos adjuntos, la configuración y la base de datos en el mismo manifiesto de recuperación. Una restauración limpia de Gitea solo es correcta cuando los repositorios superan fsck, los objetos LFS se descargan y las incidencias, releases y permisos de usuario coinciden con el estado anterior a la copia de seguridad.

¿Gitea necesita HTTPS detrás de un reverse proxy?

Utiliza HTTPS para el origen público de Gitea y mantén el puerto 3000 en la ruta interna. Aplica correctamente la configuración de Gitea: establece ROOT_URL y SSH_DOMAIN con las direcciones desde las que los usuarios realmente clonan. En Gitea, HTTPS protege las credenciales o el contenido de los usuarios durante el tránsito y mantiene coherente el comportamiento del cliente, que depende del origen.

¿Cómo debe probarse una actualización de Gitea?

Restaura el estado actual de Gitea en una implementación aislada, aplica la versión candidata y repite su transacción de aceptación. Presta especial atención porque las migraciones de esquema, los hooks de los repositorios, los paquetes y los runners de terceros requieren una actualización de Gitea por fases. Conserva la imagen anterior de Gitea hasta comprender sus límites de migración de datos y rollback.