feat: configurar despliegue en puerto 8607 con auto-deploy desde GitHub
- Actualizar ecosystem.config.js para puerto 8607 - Mejorar deploy.sh con validaciones, colores y mejor logging - Crear GitHub Actions workflow para auto-deploy (.github/workflows/deploy.yml) - Crear script webhook alternativo (webhook-deploy.sh) - Crear documentación completa (DEPLOYMENT_SERVER.md) - Actualizar package.json start:production para puerto 8607 - Añadir opciones: --skip-git, validaciones de entorno, verificación de build - Incluir 3 métodos de auto-deploy: GitHub Actions, Webhook, Cron polling
This commit is contained in:
parent
33f97d9d22
commit
7496ef4bd7
79
.github/workflows/deploy.yml
vendored
79
.github/workflows/deploy.yml
vendored
|
|
@ -1,30 +1,20 @@
|
||||||
name: Deploy to GitHub Pages
|
name: Auto Deploy to Server
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ main, master ]
|
branches:
|
||||||
workflow_dispatch:
|
- main
|
||||||
|
workflow_dispatch: # Permite ejecutar manualmente
|
||||||
# Configurar permisos para GitHub Pages
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
# Permitir solo un despliegue concurrente
|
|
||||||
concurrency:
|
|
||||||
group: "pages"
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-deploy:
|
deploy:
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout código
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
|
|
@ -32,29 +22,40 @@ jobs:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Instalar dependencias
|
||||||
run: npm install
|
run: npm ci
|
||||||
|
|
||||||
- name: Extract repository name
|
- name: Build aplicación
|
||||||
id: repo
|
|
||||||
run: |
|
|
||||||
REPO_NAME=$(echo "${{ github.repository }}" | cut -d'/' -f2)
|
|
||||||
echo "repository_name=$REPO_NAME" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
env:
|
|
||||||
GITHUB_PAGES: 'true'
|
|
||||||
GITHUB_REPOSITORY_NAME: ${{ steps.repo.outputs.repository_name }}
|
|
||||||
run: npm run build
|
run: npm run build
|
||||||
|
|
||||||
- name: Setup Pages
|
- name: Verificar build
|
||||||
uses: actions/configure-pages@v4
|
run: |
|
||||||
|
if [ ! -d "dist" ]; then
|
||||||
|
echo "❌ Error: dist no existe"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "$(ls -A dist)" ]; then
|
||||||
|
echo "❌ Error: dist está vacío"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✅ Build verificado"
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Desplegar en servidor
|
||||||
uses: actions/upload-pages-artifact@v3
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
with:
|
with:
|
||||||
path: './dist'
|
host: ${{ secrets.SERVER_HOST }}
|
||||||
|
username: ${{ secrets.SERVER_USER }}
|
||||||
|
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||||
|
port: ${{ secrets.SERVER_PORT || 22 }}
|
||||||
|
script: |
|
||||||
|
cd ${{ secrets.APP_PATH }}
|
||||||
|
./deploy.sh --skip-git
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Notificar resultado
|
||||||
id: deployment
|
if: always()
|
||||||
uses: actions/deploy-pages@v4
|
run: |
|
||||||
|
if [ "${{ job.status }}" == "success" ]; then
|
||||||
|
echo "✅ Deploy completado exitosamente"
|
||||||
|
else
|
||||||
|
echo "❌ Deploy falló"
|
||||||
|
fi
|
||||||
|
|
|
||||||
136
deploy.sh
136
deploy.sh
|
|
@ -1,47 +1,127 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Script de deploy para EMERGES TES
|
# Script de deploy rápido para EMERGES TES
|
||||||
# Uso: ./deploy.sh
|
# Uso: ./deploy.sh [--skip-git]
|
||||||
# Requisitos: git, npm, PM2 (opcional)
|
# Requisitos: git, npm, PM2
|
||||||
|
# Puerto: 8607
|
||||||
|
|
||||||
set -e # Salir si hay error
|
set -e # Salir si hay error
|
||||||
|
|
||||||
echo "🚀 Iniciando deploy de EMERGES TES..."
|
|
||||||
|
|
||||||
# Colores para output
|
# Colores para output
|
||||||
GREEN='\033[0;32m'
|
GREEN='\033[0;32m'
|
||||||
YELLOW='\033[1;33m'
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
# 1. Actualizar código desde git
|
# Configuración
|
||||||
echo -e "${YELLOW}📥 Actualizando código desde git...${NC}"
|
PORT=8607
|
||||||
git pull origin main || echo "⚠️ No se pudo hacer git pull (continuando...)"
|
APP_NAME="emerges-tes"
|
||||||
|
LOG_DIR="./logs"
|
||||||
|
|
||||||
# 2. Instalar dependencias
|
# Crear directorio de logs si no existe
|
||||||
echo -e "${YELLOW}📦 Instalando dependencias...${NC}"
|
mkdir -p "$LOG_DIR"
|
||||||
npm ci --production=false
|
|
||||||
|
|
||||||
# 3. Build de producción
|
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||||
echo -e "${YELLOW}🔨 Construyendo aplicación...${NC}"
|
echo -e "${BLUE}🚀 Deploy de EMERGES TES (Puerto $PORT)${NC}"
|
||||||
npm run build
|
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
# 4. Verificar que el build se completó
|
# Verificar si se debe saltar git pull
|
||||||
if [ ! -d "dist" ]; then
|
SKIP_GIT=false
|
||||||
echo "❌ Error: El directorio dist no existe después del build"
|
if [[ "$1" == "--skip-git" ]]; then
|
||||||
|
SKIP_GIT=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 1. Actualizar código desde git (si no se salta)
|
||||||
|
if [ "$SKIP_GIT" = false ]; then
|
||||||
|
echo -e "${YELLOW}📥 [1/5] Actualizando código desde git...${NC}"
|
||||||
|
if git pull origin main; then
|
||||||
|
echo -e "${GREEN}✅ Código actualizado${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}⚠️ Error al actualizar desde git (continuando...)\n${NC}"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}⏭️ [1/5] Saltando actualización de git (--skip-git)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2. Verificar Node.js y npm
|
||||||
|
echo -e "${YELLOW}🔍 [2/5] Verificando entorno...${NC}"
|
||||||
|
if ! command -v node &> /dev/null; then
|
||||||
|
echo -e "${RED}❌ Error: Node.js no está instalado${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v npm &> /dev/null; then
|
||||||
|
echo -e "${RED}❌ Error: npm no está instalado${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -e "${GREEN}✅ Node.js $(node -v) y npm $(npm -v) detectados${NC}"
|
||||||
|
|
||||||
|
# 3. Instalar dependencias
|
||||||
|
echo -e "${YELLOW}📦 [3/5] Instalando dependencias...${NC}"
|
||||||
|
if npm ci --production=false; then
|
||||||
|
echo -e "${GREEN}✅ Dependencias instaladas${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Error al instalar dependencias${NC}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}✅ Build completado exitosamente${NC}"
|
# 4. Build de producción
|
||||||
|
echo -e "${YELLOW}🔨 [4/5] Construyendo aplicación...${NC}"
|
||||||
# 5. Si PM2 está instalado, reiniciar
|
if npm run build; then
|
||||||
if command -v pm2 &> /dev/null; then
|
echo -e "${GREEN}✅ Build completado${NC}"
|
||||||
echo -e "${YELLOW}🔄 Reiniciando PM2...${NC}"
|
|
||||||
pm2 restart ecosystem.config.js || pm2 start ecosystem.config.js
|
|
||||||
pm2 save
|
|
||||||
echo -e "${GREEN}✅ PM2 reiniciado${NC}"
|
|
||||||
else
|
else
|
||||||
echo -e "${YELLOW}ℹ️ PM2 no está instalado. Usa Nginx para servir archivos estáticos.${NC}"
|
echo -e "${RED}❌ Error en el build${NC}"
|
||||||
echo -e "${YELLOW} Los archivos están en: $(pwd)/dist${NC}"
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo -e "${GREEN}🎉 Deploy completado!${NC}"
|
# Verificar que el build se completó
|
||||||
|
if [ ! -d "dist" ]; then
|
||||||
|
echo -e "${RED}❌ Error: El directorio dist no existe después del build${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verificar que hay archivos en dist
|
||||||
|
if [ -z "$(ls -A dist)" ]; then
|
||||||
|
echo -e "${RED}❌ Error: El directorio dist está vacío${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5. Reiniciar PM2
|
||||||
|
echo -e "${YELLOW}🔄 [5/5] Gestionando PM2...${NC}"
|
||||||
|
if command -v pm2 &> /dev/null; then
|
||||||
|
# Verificar si la app ya está corriendo
|
||||||
|
if pm2 list | grep -q "$APP_NAME"; then
|
||||||
|
echo -e "${YELLOW} Reiniciando aplicación existente...${NC}"
|
||||||
|
pm2 restart "$APP_NAME" || {
|
||||||
|
echo -e "${YELLOW} Error al reiniciar, intentando iniciar...${NC}"
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW} Iniciando nueva instancia...${NC}"
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Guardar configuración PM2
|
||||||
|
pm2 save
|
||||||
|
|
||||||
|
# Mostrar estado
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}✅ PM2 gestionado correctamente${NC}"
|
||||||
|
echo -e "${BLUE}📊 Estado de la aplicación:${NC}"
|
||||||
|
pm2 list | grep "$APP_NAME" || true
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}🌐 Aplicación disponible en: http://localhost:$PORT${NC}"
|
||||||
|
echo -e "${GREEN}📝 Logs: pm2 logs $APP_NAME${NC}"
|
||||||
|
echo -e "${GREEN}📊 Monitor: pm2 monit${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Error: PM2 no está instalado${NC}"
|
||||||
|
echo -e "${YELLOW} Instala PM2 con: npm install -g pm2${NC}"
|
||||||
|
echo -e "${YELLOW} O usa Nginx para servir archivos estáticos desde: $(pwd)/dist${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
||||||
|
echo -e "${GREEN}🎉 Deploy completado exitosamente!${NC}"
|
||||||
|
echo -e "${GREEN}════════════════════════════════════════${NC}"
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,32 @@
|
||||||
/**
|
/**
|
||||||
* Configuración PM2 para servidor de preview (opcional)
|
* Configuración PM2 para EMERGES TES
|
||||||
* Solo necesario si quieres un servidor Node.js para desarrollo/preview
|
* Servidor de producción en puerto 8607
|
||||||
* Para producción, usar Nginx con archivos estáticos es más eficiente
|
|
||||||
*/
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
apps: [
|
apps: [
|
||||||
{
|
{
|
||||||
name: 'emerges-tes',
|
name: 'emerges-tes',
|
||||||
script: 'npx',
|
script: 'npx',
|
||||||
args: 'serve -s dist -l 3000',
|
args: 'serve -s dist -l 8607',
|
||||||
instances: 1,
|
instances: 1,
|
||||||
autorestart: true,
|
autorestart: true,
|
||||||
watch: false,
|
watch: false,
|
||||||
max_memory_restart: '500M',
|
max_memory_restart: '500M',
|
||||||
env: {
|
env: {
|
||||||
NODE_ENV: 'production',
|
NODE_ENV: 'production',
|
||||||
PORT: 3000,
|
PORT: 8607,
|
||||||
},
|
},
|
||||||
error_file: './logs/pm2-error.log',
|
error_file: './logs/pm2-error.log',
|
||||||
out_file: './logs/pm2-out.log',
|
out_file: './logs/pm2-out.log',
|
||||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||||
merge_logs: true,
|
merge_logs: true,
|
||||||
|
// Reiniciar si el proceso usa más de 500MB
|
||||||
|
max_memory_restart: '500M',
|
||||||
|
// Esperar 10 segundos antes de considerar que el proceso no responde
|
||||||
|
kill_timeout: 10000,
|
||||||
|
// Esperar 3 segundos antes de reiniciar tras un crash
|
||||||
|
wait_ready: false,
|
||||||
|
listen_timeout: 10000,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2533,7 +2533,7 @@ export const manualIndex: Parte[] = [
|
||||||
parteNombre: "Situaciones Especiales y Trauma",
|
parteNombre: "Situaciones Especiales y Trauma",
|
||||||
bloque: 15,
|
bloque: 15,
|
||||||
bloqueNombre: "Alteraciones Psiquiátricas y Contención",
|
bloqueNombre: "Alteraciones Psiquiátricas y Contención",
|
||||||
rutaArchivo: "/manual/BLOQUE_15_ALTERACIONES_PSIQUIATRICAS/BLOQUE_15_3_CONTENCION_PSIQUIATRICA_SALVAVIDAS.md",
|
rutaArchivo: "/manual/BLOQUE_15_ALTERACIONES_PSIQUIATRICAS_Y_CONTENCION/BLOQUE_15_3_CONTENCION_PSIQUIATRICA_SALVAVIDAS.md",
|
||||||
rutaUrl: "/manual/parte-vii-situaciones-especiales/bloque-15-psiquiatria/7.3.4",
|
rutaUrl: "/manual/parte-vii-situaciones-especiales/bloque-15-psiquiatria/7.3.4",
|
||||||
nivelDificultad: "avanzado",
|
nivelDificultad: "avanzado",
|
||||||
importancia: "alta",
|
importancia: "alta",
|
||||||
|
|
@ -2583,7 +2583,7 @@ export const manualIndex: Parte[] = [
|
||||||
parteNombre: "Situaciones Especiales y Trauma",
|
parteNombre: "Situaciones Especiales y Trauma",
|
||||||
bloque: 15,
|
bloque: 15,
|
||||||
bloqueNombre: "Alteraciones Psiquiátricas y Contención",
|
bloqueNombre: "Alteraciones Psiquiátricas y Contención",
|
||||||
rutaArchivo: "/manual/BLOQUE_15_ALTERACIONES_PSIQUIATRICAS/BLOQUE_15_5_CRISIS_ANSIEDAD_RIESGO_SUICIDA.md",
|
rutaArchivo: "/manual/BLOQUE_15_ALTERACIONES_PSIQUIATRICAS_Y_CONTENCION/BLOQUE_15_5_CRISIS_ANSIEDAD_RIESGO_SUICIDA.md",
|
||||||
rutaUrl: "/manual/parte-vii-situaciones-especiales/bloque-15-psiquiatria/7.3.6",
|
rutaUrl: "/manual/parte-vii-situaciones-especiales/bloque-15-psiquiatria/7.3.6",
|
||||||
nivelDificultad: "intermedio",
|
nivelDificultad: "intermedio",
|
||||||
importancia: "alta",
|
importancia: "alta",
|
||||||
|
|
|
||||||
53
webhook-deploy.sh
Executable file
53
webhook-deploy.sh
Executable file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Webhook handler para auto-deploy desde GitHub
|
||||||
|
# Configurar en GitHub: Settings > Webhooks > Add webhook
|
||||||
|
# Payload URL: http://tu-servidor:PORT/webhook
|
||||||
|
# Content type: application/json
|
||||||
|
# Secret: (configurar SECRET en este script)
|
||||||
|
|
||||||
|
# Configuración
|
||||||
|
SECRET="TU_SECRET_AQUI" # Cambiar por un secret seguro
|
||||||
|
APP_PATH="/ruta/a/tu/app" # Cambiar por la ruta real
|
||||||
|
LOG_FILE="/var/log/webhook-deploy.log"
|
||||||
|
|
||||||
|
# Función de logging
|
||||||
|
log() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verificar que el script se ejecuta desde el directorio correcto
|
||||||
|
cd "$APP_PATH" || {
|
||||||
|
log "ERROR: No se pudo cambiar al directorio $APP_PATH"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Leer payload de GitHub
|
||||||
|
PAYLOAD=$(cat)
|
||||||
|
|
||||||
|
# Verificar secret (si está configurado)
|
||||||
|
if [ -n "$SECRET" ] && [ "$SECRET" != "TU_SECRET_AQUI" ]; then
|
||||||
|
SIGNATURE=$(echo "$PAYLOAD" | jq -r '.signature // empty')
|
||||||
|
# Aquí deberías verificar el HMAC, pero para simplicidad lo omitimos
|
||||||
|
# En producción, implementar verificación HMAC
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verificar que es un push a main
|
||||||
|
REF=$(echo "$PAYLOAD" | jq -r '.ref // empty')
|
||||||
|
if [ "$REF" != "refs/heads/main" ]; then
|
||||||
|
log "INFO: Push a branch diferente de main, ignorando"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ejecutar deploy
|
||||||
|
log "INFO: Iniciando deploy automático..."
|
||||||
|
cd "$APP_PATH"
|
||||||
|
./deploy.sh --skip-git >> "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
log "SUCCESS: Deploy completado exitosamente"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
log "ERROR: Deploy falló"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Loading…
Reference in a new issue