Autoalojar Gitea como tu propio servidor Git
Sigue esto en tu propio servidor. Empieza gratis, sin tarjeta
Quieres tus repositorios en una máquina que controlas: código privado que nunca sale de tu infraestructura, sin precio por usuario y con una interfaz web que tu equipo ya sabe usar. Gitea te da eso en un solo contenedor: navegación de repositorios, pull requests, issues, un registro de paquetes y Git por HTTPS y por SSH. Esta guía te lleva de un servidor vacío a Gitea en tu propio dominio, con HTTPS a través de Caddy, envíos por SSH en su propio puerto y un respaldo que ya restauraste al menos una vez. La última parte muestra la versión de un clic en Railyard.
Esta guía usa Gitea 28.2.0, la versión actual, desde el registro propio de Gitea en docker.gitea.com. Gitea pasó de los números 1.x a 28.0.0 en septiembre de 2026, así que una etiqueta “28” es la versión más nueva, no un error.
Lo que necesitas
- Un servidor. Gitea es liviano. Un Hetzner CX23 (2 vCPU, 4 GB de RAM, 40 GB NVMe) cuesta 5,99 €/mes sin IVA y sobra para un equipo pequeño. Los repositorios crecen, así que vigila el disco.
- Un dominio o subdominio que puedas apuntar al servidor. Esta guía usa
git.example.com. - Acceso SSH como root o con un usuario que tenga
sudo. - Un puerto libre en el host para Git por SSH. El SSH del servidor se queda en el puerto 22, así que el servidor SSH de Gitea usa el 222, el mapeo que aparece en la documentación de Gitea.
Paso 1: Apunta el DNS al servidor y actualízalo
Crea el servidor y agrega un registro A para git.example.com que apunte a su IPv4 pública. Hazlo primero: Caddy solo puede obtener un certificado cuando el nombre ya resuelve a tu servidor.
ssh root@203.0.113.20
apt update && apt upgrade -y
Desde tu computadora, revisa el registro:
dig +short git.example.com
Deberías ver la IP de tu servidor. Si todavía no, sigue y vuelve a revisar antes del paso 5.
Paso 2: Instala Docker
Gitea y Caddy corren en contenedores, así que Docker Engine con el plugin de Compose es todo lo que necesitas:
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker compose version
Deberías ver una línea Docker Compose version.
Paso 3: Escribe el archivo de Compose
Gitea usa SQLite a menos que lo apuntes a otra base de datos. SQLite guarda todo en un solo volumen y funciona bien para un equipo pequeño, así que esta guía lo usa (las preguntas frecuentes hablan de Postgres). Crea la carpeta:
mkdir -p /opt/gitea/backups
cd /opt/gitea
Guarda esto como /opt/gitea/compose.yaml, con tu propio dominio:
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
depends_on:
- gitea
gitea:
image: docker.gitea.com/gitea:28.2.0
restart: unless-stopped
environment:
USER_UID: "1000"
USER_GID: "1000"
GITEA__server__DOMAIN: git.example.com
GITEA__server__ROOT_URL: https://git.example.com/
GITEA__server__SSH_DOMAIN: git.example.com
GITEA__server__SSH_PORT: "222"
volumes:
- gitea-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "222:22"
volumes:
gitea-data:
caddy-data:
caddy-config:
Qué hace:
- La imagen,
USER_UID/USER_GID, los montajes de zona horaria y el mapeo222:22vienen directo de la documentación de Docker de Gitea. Dentro del contenedor, un servidor SSH escucha en el 22 para Git; el host lo expone en el 222. - Las variables
GITEA__sección__CLAVEdefinen valores en elapp.inide Gitea.ROOT_URLhace que Gitea arme enlaces HTTPS, ySSH_PORThace que las URL de clonado muestren 222. También prellenan el asistente de instalación. - El puerto web de Gitea, el 3000, no se publica. Caddy lo alcanza por la red de Compose, así que la única entrada web es por HTTPS.
- Todo lo que Gitea guarda (repositorios, la base SQLite, archivos subidos y
app.ini) vive en el volumengitea-data. Un volumen con nombre también resuelve los permisos de archivos por ti.
Paso 4: Escribe el Caddyfile
Guarda esto como /opt/gitea/Caddyfile:
git.example.com {
encode zstd gzip
reverse_proxy gitea:3000
}
Caddy obtiene un certificado de Let’s Encrypt para el dominio, redirige HTTP a HTTPS y pasa la interfaz web y Git por HTTPS a Gitea. Git por SSH no pasa por Caddy: va directo al puerto 222. Revisa ambos archivos:
docker compose config --quiet && echo "compose ok"
docker compose run --rm --no-deps caddy caddy validate --config /etc/caddy/Caddyfile
Deberías ver compose ok y luego Valid configuration.
Paso 5: Abre los puertos y arranca
Permite los puertos 80, 443 y 222 en el firewall de tu proveedor de nube. Luego arranca el stack:
docker compose up -d
docker compose ps
docker compose logs -f caddy
Deberías ver caddy y gitea con estado Up, y a Caddy registrando que obtuvo un certificado para git.example.com. Presiona Ctrl+C y abre https://git.example.com. Deberías ver la página de instalación de Gitea.
Paso 6: Termina el asistente de instalación
Gitea no tiene cuenta por defecto: la primera visita abre una página de instalación que solo aparece una vez. Revisa los valores, que en su mayoría ya llenaron las variables de entorno:
- Database Type: SQLite3, con la ruta
/data/gitea/gitea.db. - SSH Server Port
222y Gitea Website URLhttps://git.example.com/. El recuadro Environment Configuration al final lista las variablesGITEA__que se escribirán en/data/gitea/conf/app.ini. - Only administrators can create user accounts (no self-registration): márcala si solo tu equipo debe tener cuentas.
- Administrator Account Settings, dentro de Optional Settings: define un usuario, un correo y una contraseña. La página lo dice claramente: si te saltas esto, el primer usuario que se registre se vuelve administrador.
Haz clic en Install Gitea. Deberías llegar a tu panel con la sesión iniciada como administrador.
Ahora prueba las dos formas de subir código. Agrega tu clave pública en Settings → SSH / GPG Keys, crea un repositorio llamado test-repo y luego, desde tu computadora:
git clone ssh://git@git.example.com:222/youradmin/test-repo.git
git clone https://git.example.com/youradmin/test-repo.git test-repo-https
Ambos clonados deberían funcionar. Usa la forma ssh:// con el puerto: la forma corta git@host:dueño/repo siempre usa el puerto 22.
Paso 7: Respalda Gitea
gitea dump escribe los repositorios, la base de datos, app.ini y los archivos subidos en un solo archivo comprimido. Tiene que correr con el usuario git, porque Gitea se niega a correr como root. Guarda esto como /opt/gitea/backup.sh:
#!/usr/bin/env bash
set -euo pipefail
cd /opt/gitea
docker compose exec -T -u git -w /tmp gitea gitea dump -c /data/gitea/conf/app.ini --file - > "backups/gitea-$(date +%F).zip"
find backups -name 'gitea-*.zip' -mtime +14 -delete
--file - manda el archivo a la salida estándar, así que llega directo al host. Hazlo ejecutable, córrelo y prográmalo a las 03:00 con crontab -e:
chmod +x /opt/gitea/backup.sh
/opt/gitea/backup.sh
unzip -l /opt/gitea/backups/gitea-$(date +%F).zip | tail -3
0 3 * * * /opt/gitea/backup.sh
Deberías ver una lista de archivos que termina con un total. Copia también los respaldos fuera del servidor, por ejemplo con rsync a otra máquina.
Para restaurar en una instalación nueva, arranca Gitea con un volumen vacío, copia el respaldo adentro y pon cada parte en su lugar:
docker compose up -d gitea
docker compose cp backups/gitea-2026-05-25.zip gitea:/tmp/restore.zip
docker compose exec gitea sh -c 'mkdir -p /tmp/r && cd /tmp/r && unzip -q /tmp/restore.zip && mkdir -p /data/gitea/conf /data/git/repositories && cp app.ini /data/gitea/conf/app.ini && cp -a data/. /data/gitea/ && cp -a repos/. /data/git/repositories/ && chown -R git:git /data/gitea /data/git'
docker compose restart gitea
docker compose exec -u git gitea gitea -c /data/gitea/conf/app.ini admin regenerate hooks
Esto sigue los pasos de restauración de la documentación de respaldos de Gitea para Docker. Deberías recuperar tus repositorios y tu cuenta de administrador, sin página de instalación.
Paso 8: Actualiza
Gitea aplica sus migraciones de base de datos al arrancar. Lee las notas de la versión, haz un respaldo, cambia la etiqueta de la imagen en compose.yaml y luego:
/opt/gitea/backup.sh
docker compose pull gitea
docker compose up -d gitea
docker compose logs -f gitea
Deberías ver que Gitea arranca y vuelve a responder. Si no arranca, el log indica la configuración o la migración con problemas; vuelve a la etiqueta anterior y restaura el respaldo si necesitas regresar.
El atajo: hazlo con Railyard
Los pasos 2 a 5 son lo que la plantilla de Gitea de Railyard hace por ti: despliega Gitea en Railyard. Railyard construye Gitea desde su repositorio con su propio Dockerfile, lo ejecuta en un servidor que es tuyo y le da una dirección HTTPS. Puedes agregar tu propio dominio desde la pestaña Domains de la app (Dominios y HTTPS). Luego terminas el mismo asistente del paso 6 en la URL de la app: pon la dirección HTTPS de la app en Gitea Website URL y crea la cuenta de administrador.
Dos cosas que conviene definir antes de crear repositorios:
- Mantén
/dataen un volumen. La plantilla no adjunta uno, así que agregadata:/dataen Volumes dentro de la configuración de la app. Los volúmenes se conservan entre despliegues, y puedes respaldar uno conrailyard volume:backup <app> data. - Elige la base de datos. La plantilla no adjunta ningún complemento de base de datos, así que Gitea usa SQLite dentro de
/data. Si prefieres Postgres, agrégalo primero desde la pestaña Resources de la app y escribe su host, nombre, usuario y contraseña en la sección de base de datos del asistente, porque cambiar de base cuando ya hay repositorios da más trabajo. Los respaldos de Postgres en Railyard están descritos en Bases de datos y respaldos.
Railyard publica el puerto web de Gitea por HTTPS, así que en Railyard clonas y subes código por HTTPS en lugar de SSH. El plan Free de Railyard incluye un servidor más un servidor de bases de datos y tres apps, sin tarjeta. Pro cuesta US$19/mes y Team US$49/mes, por equipo.
Solución de problemas
address already in use en el puerto 80, 443 o 222. Encuentra qué está escuchando con ss -tlnp | grep -E ':(80|443|222)\s'. Para el 222, puedes elegir otro puerto en el host (2222:22, por ejemplo) siempre que GITEA__server__SSH_PORT coincida.
Las URL de clonado muestran el host, el puerto o http:// equivocados. Gitea escribe estos valores en /data/gitea/conf/app.ini. Revisa ROOT_URL, DOMAIN, SSH_DOMAIN y SSH_PORT en el entorno, recrea el contenedor con docker compose up -d gitea y confirma que los valores cambiaron en app.ini.
Caddy no obtiene el certificado. Revisa que dig +short git.example.com devuelva la IP de tu servidor y que el puerto 80 esté abierto en el firewall de tu proveedor, ya que Let’s Encrypt valida por ahí. Caddy reintenta solo cuando el DNS está bien.
Permission denied (publickey) al clonar por SSH. Asegúrate de que la clave esté agregada en Gitea (no en el authorized_keys del servidor), de que te conectas al puerto 222 con la forma ssh:// y de que el usuario es git, no tu usuario de Gitea.
gitea dump dice que Gitea no debe correr como root. Te faltó -u git. docker compose exec corre como root si no indicas otra cosa.
El servidor se queda sin memoria. Gitea es pequeño en reposo, pero clonar o subir un repositorio muy grande puede disparar la memoria. Revisa con dmesg | grep -i "out of memory" y docker stats, y agranda el servidor si vuelve a pasar.
Preguntas frecuentes
¿Alcanza con SQLite o conviene Postgres? SQLite funciona bien para un equipo pequeño. La documentación de Docker de Gitea incluye una variante con Postgres: agrega un servicio db y define GITEA__database__DB_TYPE=postgres, GITEA__database__HOST=db:5432, GITEA__database__NAME, GITEA__database__USER y GITEA__database__PASSWD en el servicio de Gitea. Decídelo antes de la primera instalación, porque el asistente escribe esa elección en app.ini.
¿Puedo traer mis repositorios de GitHub o GitLab? Sí. La página New Migration de Gitea tiene importadores para GitHub, GitLab, Gitea y otros servicios, además de una opción de Git simple para cualquier URL. Los importadores de cada servicio pueden traer más que el código, como issues y releases, según el origen.
¿Gitea tiene CI como GitHub Actions? Gitea Actions usa archivos de workflow parecidos a la sintaxis de GitHub Actions y los ejecuta en un runner aparte que instalas tú. Configurar ese runner queda fuera de esta guía.
¿Por qué el puerto 222? Deja el inicio de sesión SSH del servidor en el 22. Cualquier puerto libre sirve si SSH_PORT coincide con el lado del host del mapeo.
Un servidor Git autoalojado se reduce sobre todo a tres cosas: las URL correctas en app.ini, un puerto SSH que no choque con el tuyo y un respaldo que de verdad restauraste. Déjalas bien desde el primer día y Gitea prácticamente se cuida solo.
Por qué eligen Railyard para esto
- Tu propia cuenta en la nube. Despliega en DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, o cualquier servidor Linux por SSH, facturado directamente por tu proveedor, sin márgenes adicionales.
- Un precio fijo por equipo. El plan Free es gratis para siempre: un servidor más un servidor de base de datos, tres apps, sin tarjeta. Pro cuesta $19 al mes por hasta cinco servidores y apps ilimitadas. Team cuesta $49 al mes con servidores ilimitados. Sin cargos por app, por despliegue, por asiento ni por gigabyte.
- Plantillas de un clic. Despliega apps de código abierto, como bases de datos, analítica y herramientas de desarrollo, en tu propio servidor con un clic.
- Bases de datos administradas. Postgres, MySQL y Redis, con copias de seguridad programadas y verificadas por restauración, y recuperación a un punto en el tiempo.
- Despliegue con git push. Despliega desde GitHub, GitLab o la CLI, con HTTPS automático y lanzamientos sin tiempo de inactividad.