# Git Deploy

> Conecta tu servidor a un repositorio de GitHub, GitLab, Gitea o Forgejo y despliega automáticamente en cada push, release o tag, con rutas protegidas, reinicios, checks de CI y rollback en un clic.

La pestaña **Git Deploy** del Portal conecta tu servidor con un repositorio de Git en **GitHub**, **GitLab**, **Gitea** o **Forgejo**. Sus archivos se copian automáticamente a tu servidor en cada push, cuando publicas una release, cuando subes un tag o cuando haces clic en un botón. Si quieres, tu servidor se detiene de forma limpia antes del despliegue y se vuelve a iniciar después.

En resumen: sube tu código y unos segundos después se ejecuta en tu servidor. Se acabó subir archivos por SFTP, descomprimir ZIPs en el gestor de archivos y olvidarte de reiniciar.

## Lo que aprenderás

- Cómo conectar un repositorio, con la app de GitHub Daki Git Deploy o con un token de acceso
- Cuándo se ejecuta un despliegue y cómo lanzarlo tú mismo
- Cómo mantener a salvo mundos, bases de datos y archivos `.env` con rutas protegidas
- Cómo funcionan los reinicios, el historial de despliegues, los rollbacks y el estado en tu repositorio
- Cómo dar a tu equipo los permisos adecuados

---

## Para quién es

- **Desarrolladores de bots de Discord y de apps en Node.js, Python o Java** cuyo código ya está en GitHub o GitLab.
- **Redes de Minecraft y equipos de servidores de juegos** que guardan plugins, configuraciones o datapacks en un repositorio y quieren que los cambios se publiquen de forma trazable.
- **Equipos:** varias personas trabajan en el repositorio, el servidor siempre está al día y los permisos de subusuario deciden exactamente quién puede desplegar.
- **Proyectos basados en releases:** solo llegan al servidor las versiones publicadas (por ejemplo, un `.jar` terminado de una release), no cada trabajo en curso.

---

## Antes de empezar

- Un servidor en el Portal que muestre la pestaña **Git Deploy**. Está en la navegación del servidor, bajo **Essentials**, justo después de **Files** por defecto.
- Un repositorio en GitHub (github.com), GitLab (gitlab.com o tu propia instancia; se incluyen subgrupos como `group/subgroup/project`), Gitea o Forgejo (por ejemplo Codeberg o tu propia instancia). Funcionan tanto repositorios públicos como privados.

> **Nota:** Daki decide según el tipo de servidor (egg) si la pestaña se muestra. Si no ves **Git Deploy**, no está activada para el tipo de tu servidor.

> **Info:** Esta guía usa las etiquetas en inglés de la pestaña Git Deploy. La pestaña está disponible en 19 idiomas y sigue el idioma que hayas elegido en el Portal; los botones están en el mismo sitio en todos los idiomas.

---

## Inicio rápido con GitHub (recomendado)

La forma más rápida: conéctate con **Daki Git Deploy**, la app oficial de GitHub de Daki Hosting. Inicias sesión en GitHub y eliges tus repositorios, **sin necesidad de token ni webhook**.

**Paso 1: Abre la pestaña Git Deploy**

En el Portal, abre tu servidor y ve a la pestaña **Git Deploy**. En **Git service**, elige **GitHub**.

**Paso 2: Conecta con GitHub**

En el cuadro **GitHub access**, haz clic en **Connect with GitHub**. Inicia sesión en GitHub y autoriza la app.

La primera vez, GitHub te lleva directamente a elegir a qué repositorios puede acceder la app (**All repositories** o solo los seleccionados): un solo paso en lugar de dos. Después vuelves al Portal y el cuadro **GitHub access** muestra **Connected via Daki Git Deploy as** con tu nombre de GitHub. El cuadro **Webhook** confirma que no hay nada que configurar: los push y las releases llegan por la app por sí solos.

**Paso 3: Elige tu repositorio y rama**

Haz clic en **Choose from my repositories** y selecciona tu repositorio, o pega la URL web o de clonado, o escribe la ruta. Haz clic en **Load branches** y elige la rama a desplegar. Déjala vacía para usar la rama por defecto del repositorio.

**Paso 4: Elige cuándo y cómo desplegar**

En **When to deploy**, elige un modo (por ejemplo **Every push**). Después define la carpeta de destino, tus [rutas protegidas](#protected-paths) y el [comportamiento de reinicio](#restart-behavior).

**Paso 5: Guarda**

Haz clic en **Save settings** en la barra inferior. Eso es todo: la cabecera de la pestaña muestra **Automatic deploys on**, y tu siguiente push se despliega automáticamente. Para desplegar ya mismo, haz clic en **Deploy now** arriba a la derecha.

- **Permitir otro repositorio:** **Choose repositories on GitHub** vuelve a abrir la selección de repositorios en GitHub, donde eliges a qué repositorios puede acceder Daki Git Deploy.
- **Quitar la conexión:** haz clic en **Disconnect**. Entonces el servidor ya no despliega desde repositorios privados.

> **Consejo:** No tienes que renovar nada nunca. Para cada despliegue, el Portal obtiene de GitHub una clave nueva y de corta duración (válida 1 hora) que solo llega al único repositorio de tu servidor. Esto ocurre en segundo plano.

---

## Inicio rápido con un token de acceso

Para **GitLab**, **Gitea** y **Forgejo** (y para GitHub si lo prefieres), guardas un token de acceso personal. Los repositorios públicos funcionan sin ningún token.

**Paso 1: Elige el servicio de Git**

Abre tu servidor → **Git Deploy** y elige el **Git service**. Para tu propia instancia de GitLab, Gitea o Forgejo, introduce la URL del servidor (por ejemplo `https://codeberg.org` o `https://git.example.com`). Para gitlab.com, déjala vacía.

**Paso 2: Introduce el repositorio**

Escribe el repositorio como ruta (`owner/name`) o pega simplemente su URL web o de clonado. Para un repositorio **público**, eso es todo lo que necesitas — sin token, el cuadro de acceso muestra **No token – public repositories only**.

**Paso 3: Guarda un token para repositorios privados**

Con GitHub, primero haz clic en **Use an own access token instead** en el cuadro **GitHub access**. Luego crea un token en tu proveedor de Git (el enlace **Create a token on …** del Portal te lleva directamente a la página correcta) y guárdalo en **Personal access token**. El Portal comprueba el token al momento. Consulta [Permisos del token](#token-permissions) para ver los permisos que necesita.

**Paso 4: Elige tus ajustes y guarda**

Elige cuándo desplegar, la carpeta de destino, las rutas protegidas y el comportamiento de reinicio, y haz clic en **Save settings**.

**Paso 5: Añade el webhook**

El cuadro **Webhook** muestra la **Payload URL** y el **Secret**, cada uno con un botón de copiar. Añádelos a tu repositorio como se describe en [Configura el webhook](#set-up-the-webhook). Debajo del cuadro, **Last delivery** indica si el webhook llega.

**Paso 6: Activa los despliegues automáticos**

Activa **Automatic deploys active**.

### Permisos del token

| Proveedor | Tipo de token | Permisos para despliegues | También necesario para el estado en tu repositorio |
| :--- | :--- | :--- | :--- |
| GitHub | Fine-grained token, solo para este repositorio | *Contents: Read-only* (para **Wait for CI checks** también *Actions: Read-only*) | *Commit statuses* y *Deployments*: *Read and write* |
| GitLab | Token de acceso personal, de proyecto o de grupo | `read_api` + `read_repository` | `api` en lugar de `read_api`, rol Developer |
| Gitea / Forgejo | Settings → Applications | `repository: Read`, `user: Read` | `repository: Read and Write` |

Si solo falta el permiso de escritura para el estado, tu servidor se despliega igualmente: el registro del despliegue muestra una nota.

### Configura el webhook

**GitHub**

En tu repositorio, ve a **Settings → Webhooks → Add webhook**:

1. Pega la **Payload URL** y el **Secret** del Portal.
2. Pon el tipo de contenido en `application/json`.
3. En los eventos, elige **Just the push event**. En modo release, elige **Releases** en su lugar.

**GitLab**

En tu proyecto, ve a **Settings → Webhooks**:

1. Pega la **Payload URL** como URL y el **Secret** en **Secret token**.
2. En los disparadores, marca **Push events**. En modo tag, marca **Tag push events**; en modo release, **Releases events**.

**Gitea / Forgejo**

En tu repositorio, ve a **Settings → Webhooks → Add webhook** y elige Gitea o Forgejo:

1. Pega la **Payload URL**, pon el tipo de contenido en `application/json` e introduce el **Secret**.
2. Elige **Push events** o, en modo release, **Custom events → Release**.

> **Consejo:** ¿Tu proveedor de Git no puede acceder al Portal, por ejemplo porque tu instancia de Gitea está en tu red doméstica? Elige un intervalo en **Also check … for updates** en su lugar (por ejemplo **Also check Gitea for updates**). La primera comprobación despliega el estado actual una vez.

---

## Cuándo se hace un despliegue

En **When to deploy**, elige uno de los cuatro modos:

| Modo | Qué se despliega |
| :--- | :--- |
| **Manual** | Solo cuando alguien hace clic en **Deploy now**. |
| **Every push** | Cada push a la rama elegida. |
| **Releases** | Solo cuando se publica una release. Despliega el **código fuente** de la release o un **archivo de release** (por ejemplo `*.jar`), opcionalmente guardado con un nombre fijo (por ejemplo `server.jar`) y, si es un `.zip`, opcionalmente extraído. Se pueden incluir o excluir las pre-releases. |
| **Tags** | Cuando se sube un tag que coincide con un patrón, por ejemplo `v*`. |

### Disparadores

- **Webhook:** tu proveedor de Git informa de los cambios al momento, y el despliegue empieza en segundos. Con la app de GitHub esto ocurre automáticamente, sin un webhook propio.
- **Comprobaciones de actualizaciones (polling):** opcional, para los casos en que tu proveedor de Git no puede acceder al Portal. Intervalos de 5 minutos a 1 día.
- **Deploy now:** en cualquier momento, con un clic. En modo release puedes elegir una release concreta.
- **Saltar un push:** pon `[skip deploy]` en el mensaje del commit y ese push no se despliega. `[deploy skip]` y `[no deploy]` también funcionan.

### Esperar a los checks de CI

Con **Wait for CI checks** activado (solo en modo **Every push**), un commit se despliega solo cuando su CI está en verde: se admiten GitHub Actions, GitLab CI y Gitea/Forgejo Actions. Si el CI falla, el despliegue se omite.

---

## Todos los ajustes explicados

| Sección | Ajuste | Qué hace |
| :--- | :--- | :--- |
| Repositorio | **Git service** | GitHub, GitLab, Gitea o Forgejo |
| Repositorio | **Server URL** | Solo para instancias propias; debe ser accesible desde internet |
| Repositorio | **Repository** | `owner/name` o una URL; **Choose from my repositories** muestra una lista |
| Repositorio | **Branch** | Vacío = rama por defecto; **Load branches** muestra una lista |
| Cuándo desplegar | **Manual** / **Every push** / **Releases** / **Tags** | Consulta [Cuándo se hace un despliegue](#when-a-deploy-runs) |
| Cuándo desplegar | **Wait for CI checks** | Solo con **Every push** |
| Cuándo desplegar | **Include pre-releases**, **What to deploy** (**Source code** / **Release file**), **Save as**, **Extract .zip files instead of uploading them** | Solo con **Releases** |
| Cuándo desplegar | **Tag pattern** | Solo con **Tags**, por ejemplo `v*`; vacío = todos los tags |
| Cuándo desplegar | **Also check … for updates** (con el nombre de tu servicio Git, por ejemplo **Also check GitHub for updates**) | Polling: **Never (webhook only)**, 5/10/15/30 min, 1/3/6/12/24 h |
| Cuándo desplegar | **Automatic deploys active** | Desactivado pausa el webhook y el polling; **Deploy now** sigue funcionando |
| Cuándo desplegar | **Show deploys in the repository** | Estado en el commit; consulta [Estado en tu repositorio](#status-in-your-repository) |
| Archivos | **Folder in the repository** | Despliega solo una subcarpeta, por ejemplo `dist`; vacío = todo |
| Archivos | **Target folder on the server** | Dónde van los archivos; `/` = la carpeta principal de tu servidor |
| Archivos | **Protected paths** | Una regla por línea, consulta [Rutas protegidas](#protected-paths) |
| Archivos | **Remove files that were deleted from the repository** | Limpieza opcional, consulta más abajo |
| Reinicio | **Restart if running** / **Always start** / **Do not restart** | Consulta [Comportamiento al reiniciar](#restart-behavior) |
| Reinicio | **If the server does not stop** | Matar inmediatamente o tras 5 s, 10 s (por defecto: **Kill after 10 seconds**), 15 s, 30 s, 1 min, 2 min o 5 min |

Los cambios solo se aplican cuando haces clic en **Save settings**. Mientras haya algo sin guardar, una barra en la parte inferior muestra **Discard** y **Save settings**, y **Deploy now** queda bloqueado.

**Remove files that were deleted from the repository** solo elimina los archivos que un despliegue anterior escribió por sí mismo: nunca las rutas protegidas ni los archivos que creaste tú. Las carpetas vacías se mantienen.

---

## Rutas protegidas

Los archivos y carpetas en **Protected paths** **nunca se sobrescriben ni se eliminan** en un despliegue. Si todavía no existen, se crean una sola vez. Perfecto para mundos de juego, bases de datos y contraseñas.

Escribe una regla por línea, relativa a la carpeta de destino. Las líneas vacías y las que empiezan por `#` se ignoran. `*` nunca coincide a través de un `/`.

| Regla | Protege |
| :--- | :--- |
| `world/` | Cada carpeta llamada `world`, a cualquier profundidad |
| `/world/` | Solo `world` directamente en la carpeta de destino |
| `*.db` | Cada archivo que termina en `.db`, en cualquier lugar |
| `.env` | Cada archivo llamado `.env`, en cualquier lugar |
| `/config.yml` | Solo `config.yml` directamente en la carpeta de destino |
| `plugins/*/config.yml` | `config.yml` en cada subcarpeta directa de `plugins` |

Ejemplos típicos:

**Minecraft**

```

world/

world_nether/

world_the_end/

plugins/*/config.yml

whitelist.json

ops.json

banned-*.json

```

**Bot de Discord / Node.js**

```

.env

*.db

*.sqlite

node_modules/

data/

```

**Python**

```

.env

*.db

venv/

```

---

## Comportamiento al reiniciar

| Opción | Qué ocurre |
| :--- | :--- |
| **Restart if running** | El servidor se detiene antes de escribir los archivos y se vuelve a iniciar después. Un servidor apagado sigue apagado. |
| **Always start** | Igual que lo anterior, y un servidor apagado se inicia después del despliegue. |
| **Do not restart** | Los archivos se reemplazan mientras el servidor sigue funcionando. |

**If the server does not stop:** algunos programas, sobre todo las apps en Node.js, ignoran la señal de parada. Entonces el servidor se mata tras el tiempo que elijas (inmediatamente, de 5 segundos a 5 minutos; **Kill after 10 seconds** por defecto) para que el despliegue no se quede colgado. Matar al instante es lo más rápido, pero no da tiempo al servidor a guardar nada.

> **Nota:** Dos redes de seguridad: si el servidor no se apaga del todo, **no se cambia ningún archivo**. Si el despliegue falla después de detener el servidor, el servidor se **vuelve a iniciar**.

---

## Qué ocurre durante un despliegue

1. Un disparador (push, release, tag, comprobación de actualizaciones o botón) crea un despliegue.
2. Si **Wait for CI checks** está activado, espera a que los checks de CI estén en verde (**Waiting**).
3. El **Portal** descarga el archivo comprimido de tu proveedor de Git. Tus credenciales nunca salen del Portal ni llegan a tu servidor.
4. El archivo se prepara: solo la carpeta elegida, sin las rutas protegidas, y se descarta el contenido no seguro, como los enlaces simbólicos.
5. Según tus ajustes, el servidor se detiene (y se mata tras el tiempo elegido si hace falta).
6. Los archivos se escriben en la carpeta de destino; opcionalmente, se eliminan los archivos borrados.
7. Según tus ajustes, el servidor se vuelve a iniciar.
8. El resultado y el registro completo aparecen en el historial y, si está activado, como estado en el commit.

Un despliegue suele tardar **10–40 segundos**, más el tiempo que tu servidor necesite para detenerse.

---

## Historial, registros y rollback

La lista **Deployments** al final de la pestaña muestra cada despliegue con su estado, rama y commit (por ejemplo `main @ 75cd0a1`), número, disparador, la persona que lo inició, la hora y el mensaje del commit. La cabecera de la pestaña muestra cuándo se desplegó el servidor por última vez.

| Estado | Significado |
| :--- | :--- |
| **Waiting** | Esperando a los checks de CI |
| **Scheduled** | En cola, empieza enseguida |
| **Running** | El despliegue está en curso |
| **Deployed** | Terminado con éxito |
| **Failed** | Algo salió mal; el registro muestra qué |
| **Skipped** | No se desplegó, por ejemplo porque el CI falló o el commit dice `[skip deploy]` |
| **Cancelled** | Cancelado antes de empezar |

- **Registro:** cada despliegue tiene un registro en vivo que se actualiza mientras se ejecuta. **Hide log** lo vuelve a cerrar.
- **Rollback en un clic:** haz clic en **Deploy again** en un despliegue anterior para volver a publicar ese estado.
- **Cancelar:** los despliegues en espera o programados se pueden cancelar.

Varios servidores pueden desplegar al mismo tiempo, pero cada servidor solo ejecuta un despliegue a la vez. Un nuevo disparador reemplaza un despliegue anterior que todavía esté en espera.

---

## Estado en tu repositorio

Con **Show deploys in the repository** activado, tu commit muestra un estado **Daki Hosting / *nombre de tu servidor***: amarillo mientras se ejecuta el despliegue, después una marca verde o una cruz roja, con un enlace a la pestaña Git Deploy.

- En GitHub, el despliegue también aparece en **Deployments**, con el nombre de tu servidor como entorno.
- Con la app de GitHub, el estado lo escribe **Daki Git Deploy** y muestra su logo; no hay nada más que configurar. Con un token, muestra la imagen de la cuenta del token, y el token necesita permisos de escritura (consulta [Permisos del token](#token-permissions)).
- Puedes desactivarlo por servidor. Solo el estado y el enlace son públicos: sin registros ni detalles de errores.

---

## Equipos y permisos de subusuarios

Los [subusuarios](https://daki.cc/es/wiki/guides/subusers) obtienen su propio grupo de permisos **Git Deploy**:

| Permiso | Permite |
| :--- | :--- |
| **view** (`github.read`) | Ver los ajustes, la dirección del webhook y el historial con registros |
| **deploy** (`github.deploy`) | **Deploy now**, **Deploy again** y cancelar despliegues |
| **change settings** (`github.update`) | Repositorio, acceso, webhook y todos los ajustes |

Los subusuarios **no** tienen acceso a Git Deploy por defecto: tú decides quién recibe cada permiso. El propietario del servidor siempre puede hacerlo todo.

---

## Seguridad

- Los tokens y secretos se guardan **cifrados** y **nunca se envían a tu navegador**.
- Con la app de GitHub, no hay ningún token tuyo de larga duración para los despliegues: cada despliegue usa una clave de corta duración (1 hora) que llega **solo al repositorio de tu servidor**.
- Tu propio acceso a GitHub decide qué repositorios puedes conectar. Nadie puede traer repositorios de otra persona a su servidor.
- Los webhooks van **firmados** con un secreto propio para cada servidor. Las entregas con un secreto incorrecto o de otro repositorio se rechazan.
- Solo la persona que guardó el token puede cambiar el repositorio, así que los subusuarios no pueden usar el token del propietario para cargar otros repositorios privados.
- Si cambias el **Git service** o la URL del servidor, el token guardado se elimina automáticamente al guardar.
- Las rutas protegidas nunca se sobrescriben, y **Remove files that were deleted from the repository** solo elimina lo que Git Deploy escribió.
- El estado público en tu repositorio no contiene registros ni detalles de errores.

---

## Límites conocidos

- Un repositorio y un acceso por servidor.
- Cada servidor solo ejecuta un despliegue a la vez.
- El estado en tu repositorio solo aparece cuando el despliegue empieza de verdad, no mientras espera al CI.
- Los archivos de release solo se extraen si son `.zip`; un `.tar.gz` se sube como archivo.
- Las carpetas vacías se mantienen tras **Remove files that were deleted from the repository**.
- Los enlaces simbólicos del repositorio no se despliegan.
- GitLab no tiene pre-releases; una release con fecha futura cuenta como pre-release.
- GitLab: los archivos de release subidos al proyecto (`/uploads/…`) no se pueden descargar con un token desde proyectos privados; sí funcionan los enlaces al registro de paquetes.
- **Connect with GitHub** solo está disponible para GitHub; GitLab, Gitea y Forgejo usan un token.

---

## Preguntas frecuentes y solución de problemas

**¿Tengo que renovar mi token periódicamente?**

No con la app de GitHub: el Portal obtiene automáticamente una clave nueva para cada despliegue. Un token propio es válido durante el tiempo que elegiste al crearlo en tu proveedor de Git; cuando caduque, basta con guardar uno nuevo.

**Mi repositorio no aparece en la lista (app de GitHub)**

Haz clic en **Choose repositories on GitHub** y permite que la app acceda al repositorio.

**El despliegue se queda en Scheduled**

Espera un momento. Si se mantiene así más de unos minutos, [contacta con soporte](https://daki.cc/es/wiki/guides/support).

**El webhook no llega o GitHub muestra el error 401**

El secreto no coincide. Copia el secreto del Portal y vuelve a introducirlo en el webhook. **New secret** crea uno nuevo; en ese caso, cámbialo también en tu proveedor de Git.

**¿Por qué se omitió mi despliegue?**

Posibles motivos: fallaron los checks de CI, el mensaje del commit contiene `[skip deploy]` o un disparador más reciente reemplazó un despliegue que seguía en espera. El motivo aparece en la fila del despliegue.

**No veo ningún estado en mi commit**

**Show deploys in the repository** tiene que estar activado. Con un token, el token también necesita permisos de escritura (consulta [Permisos del token](#token-permissions)); el registro del despliegue muestra el motivo.

**El despliegue falla con “The node rejected the request”**

El tipo de servidor no permite ciertos archivos, o el disco está lleno. El registro muestra los detalles.

**La URL de mi instancia propia de Gitea es rechazada**

Las instancias propias deben ser accesibles desde internet. Las direcciones de una red doméstica, como `192.168.x.x`, no funcionan.

**¿Cómo hago un rollback?**

En el historial, haz clic en **Deploy again** en el despliegue anterior al que quieres volver.

**¿Se sobrescribirá mi mundo de juego o mi base de datos?**

No, si están en **Protected paths** (por ejemplo `world/` o `*.db`).

**¿Quién de mi equipo puede desplegar?**

Solo las personas con el permiso **deploy** en el grupo **Git Deploy** de los ajustes de subusuarios del servidor. El propietario del servidor siempre puede hacerlo todo.

---

## Próximos pasos

- [Subusuarios](https://daki.cc/es/wiki/guides/subusers): da acceso a tu equipo y decide quién puede desplegar.
- [Variables de entorno](https://daki.cc/es/wiki/guides/environment-variables): mantén tokens y contraseñas fuera de tu repositorio.
- [Ajustes de inicio](https://daki.cc/es/wiki/guides/startup-settings): define el comando de inicio con el que se ejecuta tu código desplegado.
- [Copias de seguridad](https://daki.cc/es/wiki/guides/backups): guarda copias de seguridad automáticas de tu servidor en Google Drive.

---
Source: https://daki.cc/es/wiki/guides/git-deploy
