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
91
.github/workflows/deploy.yml
vendored
91
.github/workflows/deploy.yml
vendored
|
|
@ -1,60 +1,61 @@
|
|||
name: Deploy to GitHub Pages
|
||||
name: Auto Deploy to Server
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, master ]
|
||||
workflow_dispatch:
|
||||
|
||||
# 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
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch: # Permite ejecutar manualmente
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout código
|
||||
uses: actions/checkout@v4
|
||||
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Extract repository name
|
||||
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 }}
|
||||
|
||||
- name: Instalar dependencias
|
||||
run: npm ci
|
||||
|
||||
- name: Build aplicación
|
||||
run: npm run build
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
|
||||
- name: Verificar build
|
||||
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: Desplegar en servidor
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
path: './dist'
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
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: Notificar resultado
|
||||
if: always()
|
||||
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
|
||||
|
||||
# Script de deploy para EMERGES TES
|
||||
# Uso: ./deploy.sh
|
||||
# Requisitos: git, npm, PM2 (opcional)
|
||||
# Script de deploy rápido para EMERGES TES
|
||||
# Uso: ./deploy.sh [--skip-git]
|
||||
# Requisitos: git, npm, PM2
|
||||
# Puerto: 8607
|
||||
|
||||
set -e # Salir si hay error
|
||||
|
||||
echo "🚀 Iniciando deploy de EMERGES TES..."
|
||||
|
||||
# Colores para output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 1. Actualizar código desde git
|
||||
echo -e "${YELLOW}📥 Actualizando código desde git...${NC}"
|
||||
git pull origin main || echo "⚠️ No se pudo hacer git pull (continuando...)"
|
||||
# Configuración
|
||||
PORT=8607
|
||||
APP_NAME="emerges-tes"
|
||||
LOG_DIR="./logs"
|
||||
|
||||
# 2. Instalar dependencias
|
||||
echo -e "${YELLOW}📦 Instalando dependencias...${NC}"
|
||||
npm ci --production=false
|
||||
# Crear directorio de logs si no existe
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# 3. Build de producción
|
||||
echo -e "${YELLOW}🔨 Construyendo aplicación...${NC}"
|
||||
npm run build
|
||||
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE}🚀 Deploy de EMERGES TES (Puerto $PORT)${NC}"
|
||||
echo -e "${BLUE}════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
|
||||
# 4. Verificar que el build se completó
|
||||
if [ ! -d "dist" ]; then
|
||||
echo "❌ Error: El directorio dist no existe después del build"
|
||||
# Verificar si se debe saltar git pull
|
||||
SKIP_GIT=false
|
||||
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
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Build completado exitosamente${NC}"
|
||||
|
||||
# 5. Si PM2 está instalado, reiniciar
|
||||
if command -v pm2 &> /dev/null; then
|
||||
echo -e "${YELLOW}🔄 Reiniciando PM2...${NC}"
|
||||
pm2 restart ecosystem.config.js || pm2 start ecosystem.config.js
|
||||
pm2 save
|
||||
echo -e "${GREEN}✅ PM2 reiniciado${NC}"
|
||||
# 4. Build de producción
|
||||
echo -e "${YELLOW}🔨 [4/5] Construyendo aplicación...${NC}"
|
||||
if npm run build; then
|
||||
echo -e "${GREEN}✅ Build completado${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}ℹ️ PM2 no está instalado. Usa Nginx para servir archivos estáticos.${NC}"
|
||||
echo -e "${YELLOW} Los archivos están en: $(pwd)/dist${NC}"
|
||||
echo -e "${RED}❌ Error en el build${NC}"
|
||||
exit 1
|
||||
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)
|
||||
* Solo necesario si quieres un servidor Node.js para desarrollo/preview
|
||||
* Para producción, usar Nginx con archivos estáticos es más eficiente
|
||||
* Configuración PM2 para EMERGES TES
|
||||
* Servidor de producción en puerto 8607
|
||||
*/
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'emerges-tes',
|
||||
script: 'npx',
|
||||
args: 'serve -s dist -l 3000',
|
||||
args: 'serve -s dist -l 8607',
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: '500M',
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
PORT: 3000,
|
||||
PORT: 8607,
|
||||
},
|
||||
error_file: './logs/pm2-error.log',
|
||||
out_file: './logs/pm2-out.log',
|
||||
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
|
||||
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",
|
||||
bloque: 15,
|
||||
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",
|
||||
nivelDificultad: "avanzado",
|
||||
importancia: "alta",
|
||||
|
|
@ -2583,7 +2583,7 @@ export const manualIndex: Parte[] = [
|
|||
parteNombre: "Situaciones Especiales y Trauma",
|
||||
bloque: 15,
|
||||
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",
|
||||
nivelDificultad: "intermedio",
|
||||
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