You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
senzapaura_es/despliegue/desplegar.sh

88 lines
3.4 KiB

#!/usr/bin/env bash
#
# Despliegue por SSH, sin repositorio remoto.
#
# ./despliegue/desplegar.sh senzapaura@192.168.18.171
#
# Construye aquí y sube el resultado. Se hace así y no compilando en el servidor
# porque el servidor no necesita las herramientas de desarrollo —ni Vite, ni
# Playwright, ni el compilador— para servir la web: solo Node y tres paquetes.
#
# Dos decisiones que salen de haberlo hecho una vez a mano, no de suponer:
#
# - **Se sube con `tar` por SSH, no con `rsync`.** La máquina de desarrollo es
# Windows y Git Bash no trae rsync. Tar sí, y está en los dos lados.
# - **Las dependencias se resuelven aquí y se suben ya instaladas.** El servidor
# tiene salida a internet pero su DNS no resuelve `registry.npmjs.org`, así
# que `npm ci` allí falla. Da igual: los tres paquetes de producción son
# JavaScript puro, sin binarios de plataforma, y viajan tal cual.
#
# Lo que NO se sube: `.env`. Las claves se ponen a mano en el servidor una vez
# y se quedan ahí. Subirlas en cada despliegue es cómo acaban en un historial.
set -euo pipefail
DESTINO="${1:-}"
RUTA="${2:-/var/www/senzapaura}"
CLAVE="${SSH_CLAVE:-$HOME/.ssh/senzapaura_deploy}"
if [[ -z "$DESTINO" ]]; then
echo "uso: $0 usuario@servidor [ruta]" >&2
exit 1
fi
SSH=(ssh -i "$CLAVE" -o BatchMode=yes)
TEMPORAL="$(mktemp -d)"
trap 'rm -rf "$TEMPORAL"' EXIT
echo "==> Construyendo"
node scripts/construir.mjs
if [[ ! -f build/index.js ]]; then
echo "el build no ha dejado build/index.js; se aborta" >&2
exit 1
fi
echo "==> Resolviendo dependencias de producción"
cp package.json package-lock.json "$TEMPORAL/"
(cd "$TEMPORAL" && npm ci --omit=dev --silent)
# Un binario compilado para Windows no arrancaría en el servidor. Hoy no hay
# ninguno, pero si algún día se añade una dependencia que lo traiga, es mejor
# enterarse aquí que con el servicio caído.
if find "$TEMPORAL/node_modules" -name '*.node' | grep -q .; then
echo "hay binarios de plataforma en node_modules: instálalos en el servidor" >&2
find "$TEMPORAL/node_modules" -name '*.node' | head -5 >&2
exit 1
fi
echo "==> Subiendo la aplicación"
# `build` se borra antes: los nombres llevan hash y si no se acumularían sin fin.
tar -czf - build package.json package-lock.json drizzle.config.ts drizzle |
"${SSH[@]}" "$DESTINO" "rm -rf '$RUTA/build' '$RUTA/drizzle' && tar -xzf - -C '$RUTA'"
echo "==> Subiendo dependencias"
tar -czf - -C "$TEMPORAL" node_modules |
"${SSH[@]}" "$DESTINO" "rm -rf '$RUTA/node_modules' && tar -xzf - -C '$RUTA'"
echo "==> Subiendo el audio privado"
# Sin borrar lo que hubiera: aquí puede haber material que no esté en esta
# máquina, y perderlo sería irreversible.
tar -czf - media/audio | "${SSH[@]}" "$DESTINO" "tar -xzf - -C '$RUTA'"
echo "==> Migrando la base de datos"
# Desde aquí y no en el servidor: `drizzle-kit` es una herramienta de desarrollo
# y allí no se instala. Como la base es la misma, da igual desde dónde se lance.
npm run db:migrate
echo "==> Reiniciando"
# Requiere que el usuario pueda reiniciar este servicio sin contraseña. En
# /etc/sudoers.d/senzapaura:
# senzapaura ALL=(root) NOPASSWD: /bin/systemctl restart senzapaura
"${SSH[@]}" "$DESTINO" "sudo systemctl restart senzapaura && sleep 3 && systemctl is-active senzapaura"
echo "==> Comprobando que responde"
"${SSH[@]}" "$DESTINO" "curl -sf -o /dev/null -w 'portada -> %{http_code}\n' http://127.0.0.1:3000/"
echo "Listo."

Powered by TurnKey Linux.