Un pipeline no es solo “hacer deploy automatico”. Es reducir riesgo por release y mejorar tiempo de recuperacion cuando algo sale mal.
Objetivo del pipeline
- build reproducible,
- validacion automatica,
- despliegue predecible,
- rollback claro.
Flujo recomendado
- Push a
main. - Build + checks.
- Deploy por SSH a VPS.
- Restart controlado con PM2.
- Health checks y monitoreo basico.
Workflow base en GitHub Actions
Ejemplo minimo para build + deploy por SSH cuando hay push a main:
name: ci-cd-vps
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install
run: npm ci
- name: Build
run: npm run build
- name: Deploy via SSH
uses: appleboy/[email protected]
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: |
/var/www/app/scripts/deploy.sh
Script de deploy en VPS
Separar el deploy en script evita comandos largos y reduce errores de shell dentro del workflow:
#!/usr/bin/env bash
set -euo pipefail
APP_DIR="/var/www/app"
RELEASES_DIR="$APP_DIR/releases"
CURRENT_LINK="$APP_DIR/current"
TIMESTAMP="$(date +%Y%m%d%H%M%S)"
NEW_RELEASE="$RELEASES_DIR/$TIMESTAMP"
mkdir -p "$NEW_RELEASE"
git -C "$APP_DIR" fetch origin main
git -C "$APP_DIR" archive origin/main | tar -x -C "$NEW_RELEASE"
cp "$APP_DIR/shared/.env" "$NEW_RELEASE/.env"
npm --prefix "$NEW_RELEASE" ci --omit=dev
npm --prefix "$NEW_RELEASE" run build
ln -sfn "$NEW_RELEASE" "$CURRENT_LINK"
pm2 startOrReload "$APP_DIR/shared/ecosystem.config.js" --update-env
Smoke test post deploy
Un check simple evita dejar release rota como “exito”:
#!/usr/bin/env bash
set -euo pipefail
URL="https://tu-dominio.com/health"
for i in {1..10}; do
if curl -fsS "$URL" >/dev/null; then
echo "health ok"
exit 0
fi
sleep 3
done
echo "health failed"
exit 1
Puntos de seguridad no negociables
- secrets solo en GitHub Secrets,
- claves SSH con permisos minimos,
- rotacion periodica de keys,
- headers de seguridad activos en app y nginx.
Errores tipicos en VPS CI/CD
.envmal generado por indentacion heredoc,- dependencia instalada en runner pero no en servidor,
- restart sin verificar health,
- deploy que pisa artefactos sin versionado.
Checklist de deploy seguro
- build limpio
- backup rapido de release anterior
- migraciones compatibles
- restart controlado
- smoke test de rutas criticas
Happy reading! ☕
Comments