ci: despliegue por rama en <rama>.localesp.es (Gitea Actions + host runner)
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
# CI/CD — despliegue por rama
|
||||
|
||||
Cada rama se despliega automáticamente en `https://<rama>.localesp.es`.
|
||||
|
||||
## Cómo funciona
|
||||
|
||||
```
|
||||
push a rama X
|
||||
│ Gitea Actions (workflow: .gitea/workflows/deploy.yml)
|
||||
▼
|
||||
runner self-hosted (host executor, en el propio VPS)
|
||||
│ npm ci → vite build → scripts/deploy.sh <rama>
|
||||
▼
|
||||
/opt/localesp-<slug>/ código + dist/ + node_modules (prod)
|
||||
systemd localesp-<slug>.service node server/index.js (PORT=80xx)
|
||||
nginx <slug>.localesp.es proxy_pass → localhost:80xx
|
||||
certbot *.localesp.es Let's Encrypt (si el DNS ya apunta)
|
||||
```
|
||||
|
||||
El **slug** se deriva del nombre de rama (`Feature/Foo` → `feature-foo`),
|
||||
válido como hostname DNS. Un entorno = un directorio, un servicio, un vhost y
|
||||
un puerto. La base de datos `localesp.db` de cada entorno **se conserva** entre
|
||||
despliegues (no se sobreescribe).
|
||||
|
||||
Puertos: `8080`/`8081` son entornos legacy (`localesp.service`, `localesp-master.service`);
|
||||
los nuevos empiezan en `8082`. Si la rama ya tiene su `localesp-<slug>.service`, se
|
||||
reutiliza su puerto (adopta el entorno existente).
|
||||
|
||||
## Precondición manual: el registro DNS
|
||||
|
||||
El registro A de `<rama>.localesp.es` **se crea a mano** (no está automatizado).
|
||||
|
||||
1. En el proveedor DNS de `localesp.es`, añade un registro A:
|
||||
`<rama>.localesp.es A <IP-pública-del-VPS>`
|
||||
2. Espera a que propague (`dig +short <rama>.localesp.es`).
|
||||
3. Lanza el workflow (push a la rama, o *Actions → Run workflow* en Gitea).
|
||||
|
||||
Mientras el DNS no apunte al VPS, `deploy.sh` despliega la app igualmente y la
|
||||
sirve por **HTTP**; emite el cert Let's Encrypt en cuanto detecta que el DNS ya
|
||||
resuelve. No hay que tocar nada más.
|
||||
|
||||
## Añadir una rama nueva
|
||||
|
||||
```bash
|
||||
git checkout -b mi-feature
|
||||
# ... cambios ...
|
||||
git push -u origin mi-feature
|
||||
```
|
||||
|
||||
El workflow corre solo. Si quieres URL pública: crea el registro A (arriba).
|
||||
Si no, el entorno existe pero no es alcanzable por hostname (útil para tests internos
|
||||
si añades el host a `/etc/hosts`).
|
||||
|
||||
## Borrar una rama
|
||||
|
||||
Al borrar la rama en Gitea, el job `teardown` limpia el entorno (unit systemd,
|
||||
vhost, cert y `/opt/localesp-<slug>`). También manual:
|
||||
|
||||
```bash
|
||||
ssh localesp.jumpingcrab.com 'bash /opt/localesp-master/scripts/teardown.sh mi-feature'
|
||||
```
|
||||
|
||||
## Notas sobre los entornos existentes (migración)
|
||||
|
||||
Al primer despliegue vía CI de cada rama legacy:
|
||||
|
||||
- **`master`** → `/opt/localesp-master`, reutiliza el puerto **8081** y el vhost
|
||||
existente (`master.localesp.es` y el apex `localesp.es`, que proxyan a 8081).
|
||||
Transparente, no hay corte.
|
||||
- **`prototipo-yb01`** → pasa a un entorno dedicado `/opt/localesp-prototipo-yb01`
|
||||
en un puerto nuevo (8082) y el vhost `prototipo.conf` se repunta a ese puerto.
|
||||
El antiguo `/opt/localesp` + `localesp.service` (8080) queda huérfano; puedes
|
||||
retirarlo con `systemctl disable --now localesp.service` cuando confirmes que
|
||||
el nuevo funciona.
|
||||
|
||||
## Seguridad
|
||||
|
||||
El runner (`gitea-runner`) se ejecuta como **root en el VPS de producción** y en
|
||||
modo **host** (sin contenedor): cualquier workflow que se ejecute corresponde a
|
||||
código del repo corriendo con privilegios de root en la caja. Esto es aceptable
|
||||
mientras el repo sea propio / de baja colaboración. Si entran colaboradores
|
||||
externos, conviene migrar a:
|
||||
|
||||
- runner en contenedor + despliegue por SSH (clave como secret de Gitea), o
|
||||
- *ephemeral runners* (`gitea-runner register --ephemeral`).
|
||||
|
||||
## Evolución: estrategia B (wildcard)
|
||||
|
||||
Para eliminar la precondición manual del DNS y el cert por rama, más adelante:
|
||||
|
||||
1. Registro **wildcard `*.localesp.es`** (DNS).
|
||||
2. **Wildcard cert** `*.localesp.es` vía challenge DNS-01 (una sola vez).
|
||||
3. Un único vhost `*.localesp.es` que enruta por `Host` con un `map` rama→puerto.
|
||||
|
||||
`deploy.sh` apenas cambia: se caen los pasos de creación de vhost y certbot.
|
||||
Nada de lo hecho aquí se pierde.
|
||||
|
||||
## Infra del runner (referencia)
|
||||
|
||||
Instalado en el VPS (`localesp.jumpingcrab.com`):
|
||||
|
||||
- Binario: `/usr/local/bin/gitea-runner` (v2.2.0), host executor.
|
||||
- Config: `/etc/gitea-runner/config.yaml` — etiquetas `self-hosted:host`, `linux:host`.
|
||||
- Registro: `/var/lib/gitea-runner/.runner` (instance-level, `https://git.localesp.es`).
|
||||
- Servicio: `gitea-runner.service` (systemd, `User=root`, `WorkingDirectory=/var/lib/gitea-runner`).
|
||||
|
||||
Comprobar estado: `systemctl status gitea-runner` · `journalctl -u gitea-runner -f`.
|
||||
Ver runners en Gitea: *Site administration → Actions → Runners*.
|
||||
Reference in New Issue
Block a user