4.3 KiB
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).
- En el proveedor DNS de
localesp.es, añade un registro A:<rama>.localesp.es A <IP-pública-del-VPS> - Espera a que propague (
dig +short <rama>.localesp.es). - 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
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:
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.esy el apexlocalesp.es, que proxyan a 8081). Transparente, no hay corte.prototipo-yb01→ pasa a un entorno dedicado/opt/localesp-prototipo-yb01en un puerto nuevo (8082) y el vhostprototipo.confse repunta a ese puerto. El antiguo/opt/localesp+localesp.service(8080) queda huérfano; puedes retirarlo consystemctl disable --now localesp.servicecuando 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:
- Registro wildcard
*.localesp.es(DNS). - Wildcard cert
*.localesp.esvía challenge DNS-01 (una sola vez). - Un único vhost
*.localesp.esque enruta porHostcon unmaprama→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— etiquetasself-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.