114 lines
4.8 KiB
Markdown
114 lines
4.8 KiB
Markdown
# 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 subdirectorio bajo `/opt/localesp/`,
|
|
un servicio, un vhost y un puerto. La base de datos `localesp.db` de cada
|
|
entorno **se conserva** entre despliegues (no se sobreescribe).
|
|
|
|
Puertos: los históricos son `8080` (prototipo-yb01) y `8081` (master); los
|
|
nuevos se asignan desde `8082` hacia arriba. 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'
|
|
```
|
|
|
|
## Entornos existentes (ya migrados al layout unificado)
|
|
|
|
Los entornos legacy ya están reubicados bajo `/opt/localesp/<rama>` con sus
|
|
systemd units renombradas al esquema `localesp-<slug>.service`, de modo que el
|
|
CI los **adopta** sin cambios (reutiliza puerto y vhost):
|
|
|
|
| Rama | Dir | Unit | Puerto | Hosts |
|
|
|---|---|---|---|---|
|
|
| `master` | `/opt/localesp/master` | `localesp-master.service` | 8081 | `localesp.es`, `master.localesp.es` |
|
|
| `prototipo-yb01` | `/opt/localesp/prototipo-yb01` | `localesp-prototipo-yb01.service` | 8080 | `prototipo-yb01.localesp.es` |
|
|
|
|
El antiguo `localesp.service` (sin slug) se retiró; ahora todas las units
|
|
siguen el patrón `localesp-<slug>.service`. La db de cada entorno se preservó.
|
|
|
|
## 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.
|
|
**Cadena de suministro verificada**: el binario coincide (sha256 `d6b3f5bb…`)
|
|
con el descomprimido del release oficial `gitea-runner-2.2.0-linux-amd64.xz`, cuya suma
|
|
`13357e0d…` está publicada en el release. Gitea no publica firma GPG del runner; la suma
|
|
es la garantía máxima disponible. No hay paquete `dnf` oficial (solo binario o Docker image).
|
|
- 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*.
|