MMINT Monitor

Panel de administración interna

TenantNombreEstadoMódulos UsuariosClientesProductosPublicaciones HoyÚltimo login
Salud por tenant
TenantEstadoPub. activasPub. suspendidas Último scrapeDesync estadosSin captura hoy Activas hoyAlertasSalud
El scraper corre Lun/Mié/Vie; los demás días las capturas se replican (normal). Último scrape = última corrida real del scraper · Desync estados = publicaciones cuyo estado no coincide con su captura de hoy (el auto-sync debe mantenerlo en 0).
Verde = scrapeado al día y 0 desync · Naranja = 4-5 días sin scrapear o 1-50 desync · Rojo = +6 días sin scrapear o +50 desync.
FechaTenantUsuarioAcciónDetalle
Procesos
Recursos de los servidores
● Desconectado Ctrl+C · Ctrl+D · Tab · ↑↓ funcionan normalmente
Subir archivo
Seleccioná un archivo
Base de datos
TablaRegistros
Estado del scraper
Capturas por día (últimos 14)
Última corrida por tenant
TenantÚltima corridaEstadoPublicaciones Susp. salteadasAhorro est.
Datos del panel del scraper (brand-scrap.mmint.online). El ahorro = suspendidas salteadas × 16 créditos/pub.
Backups de la base
ArchivoTamañoFecha
Backups automáticos: VPS1→VPS2 Lun/Mié/Vie 23:00. Acá podés crear/descargar dumps manuales (mysqldump + gzip).
Alertas proactivas por email
El monitor chequea cada 10 min y avisa por email si un proceso PM2 se cae, la DB no responde, o el disco/memoria superan el umbral. Avisa una vez al cambiar de estado (y cuando se recupera).
Click en cualquier comando para copiarlo. Reemplazá <proc>, <file>, <port> por lo tuyo.
📍 VPS1 = PROD (179.43.125.198 · SSH :5526 · hostname vps-5834280-x).   VPS2 = TEST (66.97.47.207 · SSH :5131 · hostname vps-5948819-x).   Estos comandos corren en la tab Terminal del panel — el selector de arriba elige el servidor. Casi todos sirven igual en ambos.

📖 Ejemplos / recetas (escenarios comunes)

🔴 Una app se cayó o anda mal → reiniciarla

Ej.: el dashboard no carga. Mirás estado, leés el error, reiniciás, verificás.
pm2 ls1. ¿Está "errored" o con ↺ alto?
pm2 logs reportes-app --err --lines 502. Ver por qué se cae (cambiá el nombre)
pm2 restart reportes-app3. Reiniciar
pm2 ls4. Confirmar que quedó "online" y ↺ dejó de subir

🌐 Un dominio da 502 / no responde

El proceso puede estar caído, en otro puerto, o nginx mal. Vas de adentro hacia afuera.
pm2 ls1. ¿El proceso del dominio está online?
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3002/2. ¿Responde local? (poné el puerto real de la app)
tail -n 30 /var/log/nginx/error.log3. ¿Qué dice nginx?
nginx -t && systemctl reload nginx4. Si tocaste config: validar y recargar

💾 Disco al 90%+ → liberar espacio

Ej.: la tab Sistema marca disco en rojo. Encontrás qué ocupa y limpiás lo seguro.
df -h /1. Confirmar cuánto queda
du -sh /home/mmint/* 2>/dev/null | sort -h | tail -152. Qué carpetas pesan más
pm2 flush3. Vaciar logs de pm2 (suele liberar harto)
journalctl --vacuum-time=7d && apt clean4. Purgar logs systemd viejos + cache de paquetes
df -h /5. Verificar que bajó

🚀 Deployar un cambio en una app (con git)

Siempre: backup → traer cambios → instalar deps → reiniciar → verificar.
cd /home/mmint/panel-web1. Ir a la carpeta de la app
git pull && npm install2. Traer cambios e instalar dependencias nuevas
pm2 restart panel-web --update-env3. Reiniciar releyendo el .env
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3010/4. Verificar que responde 200

📂 Editar un archivo en VPS2 desde el panel

Sin tocar la terminal: la tab Archivos ya maneja VPS2.
1. Andá a la tab Archivos → en el selector de arriba elegí VPS2.
2. Navegá hasta la carpeta (escribí la ruta y "Ir", o clic en las carpetas).
3. Clic en el archivo → se abre en el editor → cambiá → Guardar. Para borrar: botón Eliminar (te pregunta y avisa que es VPS2).

⚠️ Puerto ocupado tras un deploy (EADDRINUSE)

Caso real del mailer: quedó un proceso huérfano reteniendo el puerto y la app cicla.
ss -ltnp "( sport = :3001 )"1. ¿Quién tiene el puerto?
ps -ef | awk '$3==1 && /node/'2. Buscar el proceso huérfano (ppid=1)
kill <pid_huerfano>3. Matarlo (pm2 reocupa el puerto solo)
pm2 reset mmint-mailer && pm2 save4. Limpiar contador y guardar

🔒 Chequear / renovar certificados SSL

Ej.: un dominio avisa "certificado por vencer".
certbot certificates1. Ver qué vence y cuándo
certbot renew --dry-run2. Probar la renovación sin aplicar
certbot renew && systemctl reload nginx3. Renovar de verdad y recargar nginx

🟢 Conectarte a VPS2 desde la terminal del panel

Dos formas: el selector de la tab Terminal, o a mano por SSH.
A) Tab Terminal → selector arriba → VPS2 → Conectar.
ssh -p 5131 root@66.97.47.207B) A mano desde una terminal de VPS1 (sin password)
exitVolver a VPS1

📈 Ver qué consume memoria / CPU

Ej.: el server está lento o la tab Sistema marca memoria alta.
pm2 monit1. CPU/mem por proceso pm2 (q para salir)
ps aux --sort=-%mem | head -152. Top procesos del SO por memoria
free -h3. Cuánta RAM/swap libre queda

🛟 Backup manual antes de tocar algo importante

Regla de oro en PROD: copia con fecha antes de editar/migrar.
cp server.js server.js.bak-$(date +%Y%m%d-%H%M%S)Backup de un archivo con timestamp
bash /home/mmint/mmint-sistema/backup_mmint.shBackup completo de la DB (o usá la tab Backups)

🔑 Servidores & accesos

ssh -p 5131 root@66.97.47.207Desde la terminal de VPS1: entrar a VPS2 (sin password, ya configurado)
hostnameSaber en qué server estás (vps-5834280-x = VPS1 · vps-5948819-x = VPS2)
whoamiUsuario actual (debería ser root)
exitSalir de la sesión SSH (vuelve a VPS1)
wQuién está conectado al server ahora

⚙️ PM2 (procesos)

pm2 lsListar todos los procesos y su estado
pm2 logs <proc>Ver logs en vivo de un proceso
pm2 logs <proc> --lines 100Últimas 100 líneas y seguir
pm2 logs <proc> --err --lines 50Solo errores
pm2 restart <proc>Reiniciar un proceso
pm2 restart <proc> --update-envReiniciar releyendo el .env / variables de entorno
pm2 stop <proc>Detener
pm2 start <proc>Arrancar uno detenido
pm2 start app.js --name <proc>Levantar un proceso nuevo
pm2 delete <proc>Sacar de pm2 (para redeploy limpio de puerto)
pm2 describe <proc>Detalle: rutas de logs, cwd, env, puerto
pm2 monitMonitor interactivo CPU/mem por proceso
pm2 flushVaciar todos los logs de pm2 (libera disco)
pm2 reset <proc>Resetear el contador de restarts (↺)
pm2 saveGuardar la lista actual (para resurrect tras reboot) — hacelo ANTES de tocar Node/PM2
pm2 resurrectRestaurar procesos desde dump.pm2 (recuperación)
pm2 startupGenerar el script de arranque al boot
Procesos VPS1: mmint-api · mmint-scrapper · mmint-api-test · mmint-monitor · mmint-api-calc · password-manager · mmint-brand-scraper-panel · mmint-sistema · vault-monitor.   Procesos VPS2: mmint-test · mmint-mailer · scraper-panel · reportes-app · panel-web · integrador-ml · mi-mailer · sorteos · portal-clientes.

📊 Sistema & recursos

df -hUso de disco por partición
du -sh /home/mmint/* | sort -hCarpetas ordenadas por tamaño (qué ocupa)
free -hMemoria RAM usada/libre
htopMonitor interactivo (q para salir). Si no está: top
uptimeCarga (load average) y tiempo encendido
ps aux --sort=-%mem | head -15Top 15 procesos por memoria
ps -ef | grep nodeProcesos node (ojo a huérfanos con ppid=1)
kill <pid>Terminar un proceso (kill -9 <pid> si no responde)
journalctl -xe --no-pager | tail -50Últimos errores del sistema
systemctl status <svc>Estado de un servicio systemd (ej: marketing-app, nginx, mysql)
systemctl restart marketing-appReiniciar marketing-app (VPS2, es systemd no pm2)
dateFecha/hora del server
node -v; npm -vVersión de Node y npm (VPS1: Node 20.20.2 / PM2 7)

🌐 Red & puertos

ss -ltnpPuertos en escucha + qué proceso los usa
ss -ltnp "( sport = :3001 )"Quién está usando el puerto 3001 (diagnóstico EADDRINUSE)
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:4000/Probar que una app responde local (cambiá el puerto)
curl -I https://monitor.mmint.onlineVer headers/estado de un dominio público
dig +short monitor.mmint.onlineA qué IP resuelve un dominio

🟩 Nginx

nginx -tValidar la config ANTES de recargar (siempre)
systemctl reload nginxAplicar cambios sin cortar conexiones
ls /etc/nginx/sites-enabled/Vhosts activos
cat /etc/nginx/sites-available/<vhost>Ver un vhost (proxy_pass, root, server_name)
tail -f /var/log/nginx/error.logErrores de nginx en vivo
tail -f /var/log/nginx/access.logTráfico en vivo
⚠️ En VPS1 (PROD) varios vhosts NO pasan la IP real (falta X-Forwarded-For) — ya arreglado en brand. Si agregás lógica por-IP, revisá el vhost.

🔒 SSL / Certbot

certbot certificatesListar certificados y vencimientos
certbot renew --dry-runProbar la renovación sin aplicar
certbot --nginx -d dominio.comEmitir + instalar cert para un dominio
certbot delete --cert-name dominio.comBorrar un cert (al dar de baja un dominio)

🗄️ MySQL / MariaDB

mysql -u u793232474_mmint_user -p u793232474_mmint_sistemaEntrar a la DB del sistema (pide pass; está en KeePass/vault)
SHOW TABLES;Listar tablas (dentro de mysql)
DESCRIBE tenants;Ver columnas de una tabla
SHOW PROCESSLIST;Queries activas (diagnosticar DB lenta)
mysqldump --single-transaction --quick -u USER -p DB | gzip > backup.sql.gzBackup comprimido de una base
gunzip < backup.sql.gz | mysql -u USER -p DBRestaurar un dump .sql.gz
💡 Para SELECTs rápidos usá la tab SQL del panel (limita a 500 filas auto). En VPS1 el :3306 está expuesto a propósito (Looker).

💾 Backups

ls -lh /home/mmint/backups/Dumps existentes
bash /home/mmint/mmint-sistema/backup_mmint.shCorrer el backup offsite (dump PROD→VPS2 + verifica + mail). Auto: Lun/Mié/Vie 23h
crontab -lVer tareas programadas (cron) del usuario
💡 También podés crear/descargar dumps manuales desde la tab Backups del panel.

🚀 Deploy (patrón)

cd /home/mmint/<app> && git pull && npm install && pm2 restart <proc>Deploy típico de una app con git
cp archivo.js archivo.js.bak-$(date +%Y%m%d)Backup rápido con fecha ANTES de editar (siempre en PROD)
node --check server.jsValidar sintaxis de un .js sin ejecutarlo (pre-deploy)
npm rebuild⚠️ Recompilar módulos nativos (bcrypt, sharp, node-pty) tras subir Node — si no, la app crashea por ABI
Dónde vive cada app — VPS1: mmint-monitor → /home/mmint/mmint-monitor (:4000, ESTE panel) · password-manager → /home/mmint/password-manager (:3030) · vault-monitor → /home/mmint/vault-monitor (:3031, /vadmin/) · mmint-sistema (app marcas + scheduler desvíos) · mmint-brand-scraper-panel (:4001, brand-scrap) · mmint-api (:3000) · mmint-api-test (:3001) · mmint-api-calc (:3100).
Dónde vive cada app — VPS2: mmint-test → /home/mmint/mmint-test/sistema (:3002, test-brand) · panel-web → /home/mmint/panel-web (:3010) · scraper-panel → /home/mmint/scraper-panel (:3003) · mmint-mailer → /home/mmint-web/mailer (:3001) · portal-clientes → /home/portal-clientes (gunicorn /tmp/portal.sock) · reportes-app (gunicorn /tmp/reportes.sock, dash) · marketing-app (systemd :8090) · integrador-ml (:3011) · sorteos · mi-mailer. (Confirmá ruta exacta con pm2 describe <proc>.)

🌿 Git

git statusEstado del repo
git pullTraer cambios del remoto
git log --oneline -10Últimos 10 commits
git stash; git pull; git stash popGuardar cambios locales, actualizar, volver a aplicarlos
git checkout -- <file>Descartar cambios locales de un archivo
ssh -i ~/.ssh/id_rsa_github -T git@github.comProbar el acceso a GitHub con la key del server

📁 Archivos & transferencia

ls -lahListar con tamaños legibles y ocultos
tail -f <file>Seguir un archivo de log en vivo
grep -rn "texto" .Buscar texto recursivo (con nº de línea)
find /home/mmint -name "*.js" -mtime -1Archivos .js modificados en las últimas 24h
scp -P 5131 archivo root@66.97.47.207:/ruta/Copiar un archivo de VPS1 a VPS2
rsync -avz -e "ssh -p 5131" carpeta/ root@66.97.47.207:/ruta/Sincronizar una carpeta VPS1→VPS2
tar czf backup.tgz carpeta/Comprimir una carpeta (tar xzf backup.tgz para extraer)
chown -R www-data:www-data <dir>Dar permisos al usuario web (sitios estáticos)
💡 Para ver/editar archivos sin terminal usá la tab Archivos del panel (solo VPS1).
━━━ 🧰 ÁREA DE MANTENIMIENTO ━━━  Runbook completo. Empezá siempre por el chequeo de salud. En PROD (VPS1): backup con fecha antes de tocar, y reiniciá solo lo afectado.

🧰 Mantenimiento · 1. Chequeo de salud (empezá acá)

pm2 ls¿Algún proceso caído / con restarts (↺) altos?
df -h /Disco raíz — lo más crítico. Si pasa 90% actuá ya
df -i /Inodes — a veces se llenan antes que el espacio
free -hRAM y swap
uptimeLoad average (vs nº de cores)
journalctl -p err -b --no-pager | tail -30Errores del sistema desde el último boot
pm2 jlist | grep -o '"status":"[^"]*"' | sort | uniq -cResumen rápido: cuántos online vs errored
💡 En el panel: la tab Salud y la tab Sistema dan esto mismo visual por tenant/servidor.

🧰 Mantenimiento · 2. Liberar disco

du -sh /home/mmint/* 2>/dev/null | sort -h | tail -20Top carpetas de mmint por tamaño
du -ahx / 2>/dev/null | sort -h | tail -20Los 20 archivos/carpetas más grandes de TODO el server
pm2 flushVaciar todos los logs de pm2 (suele liberar bastante)
journalctl --vacuum-time=7dBorrar logs systemd de más de 7 días
journalctl --vacuum-size=200MLimitar el journal a 200 MB
apt cleanBorrar cache de paquetes .deb descargados
apt autoremove --purgeSacar paquetes/kernels huérfanos
find /home/mmint -name "*.log" -size +50M -exec ls -lh {} \;Encontrar logs de apps gigantes (>50MB)
truncate -s 0 <archivo.log>Vaciar un log SIN borrarlo (la app sigue escribiendo)
find /home/mmint/backups -name "*.sql.gz" -mtime +30 -delete⚠️ Borrar dumps de más de 30 días (verificá antes con -mtime +30 -ls)
ls -lhS /root/_restore/trash 2>/dev/nullCuarentena de la auditoría 06-16 (purgable si todo está estable)

🧰 Mantenimiento · 3. Logs

ls -lhS /var/log/*.log 2>/dev/null | headLogs del sistema por tamaño
tail -n 100 /var/log/nginx/error.logÚltimos errores de nginx
pm2 logs <proc> --err --lines 100Errores de una app puntual
logrotate -f /etc/logrotate.confForzar la rotación de logs manualmente
pm2 describe <proc> | grep "log path"Dónde escribe los logs un proceso pm2

🧰 Mantenimiento · 4. MySQL / MariaDB

systemctl status mysql¿La base está arriba? (o mariadb)
mysql -u u793232474_mmint_user -p -e "SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024) MB FROM information_schema.tables GROUP BY 1 ORDER BY 2 DESC;"Tamaño de cada base en MB
mysql -u root -p -e "SHOW BINARY LOGS;"Ver binlogs (crecen y comen disco)
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);Purgar binlogs viejos (dentro de mysql). VPS1 ya expira a 7d auto
mysqlcheck -u root -p --optimize --all-databasesOptimizar/desfragmentar tablas (en ventana, puede bloquear)
mysql -u root -p -e "SHOW PROCESSLIST;"Queries activas (diagnosticar base lenta)
⚠️ VPS1 ignora mysql.conf.d/: para variables usá SET PERSIST o poné el .cnf en conf.d/ o mariadb.conf.d/. VPS2 sí lee mysql.conf.d/.

🧰 Mantenimiento · 5. Procesos / PM2

ps -ef | awk '$3==1 && /node/'Procesos node HUÉRFANOS (ppid=1) — candidatos a kill (gotcha del mailer en :3001)
ss -ltnp "( sport = :3001 )"Quién retiene un puerto antes de relanzar (EADDRINUSE)
pm2 reset allResetear contadores de restarts de todos
pm2 saveGuardar el estado actual (SIEMPRE antes de reboot/upgrade)
pm2 updateRecargar el daemon pm2 (ojo: puede dejarlo vacío → save antes)
💡 Si una app cicla (↺ subiendo, uptime 0s): kill el huérfano ppid=1, luego pm2 reset <proc> y pm2 save. Para redeployar el mailer: pm2 delete + start (no restart).

🧰 Mantenimiento · 6. Actualizaciones

apt updateRefrescar índice de paquetes
apt list --upgradableQué hay para actualizar (revisar antes de aplicar)
apt upgradeActualizar paquetes (PROD: en ventana, con pm2 save hecho)
npm outdatedDependencias desactualizadas (dentro de la carpeta de la app)
npm auditVulnerabilidades conocidas en las deps
certbot renew --dry-runProbar la renovación de certificados
⚠️ Tras subir la versión de Node hay que npm rebuild en cada app con módulos nativos (bcrypt, sharp, node-pty) o crashean por ABI. Node es global (sin nvm).

🧰 Mantenimiento · 7. Seguridad / accesos

last -n 20Últimos logins al server
grep -i "Failed password" /var/log/auth.log | tail -20Intentos de fuerza bruta SSH
ss -ltnpQué puertos están expuestos y por qué proceso
ufw status verboseFirewall (nota: quedó SIN aplicar en ambas VPS)
ls -la ~/.ssh/authorized_keys*Claves SSH autorizadas (revisar que no sobren)

🧰 Mantenimiento · 8. Backups (verificar)

ls -lht /home/mmint/backups/ | head¿El backup corrió? (mirá la fecha del más reciente)
bash /home/mmint/mmint-sistema/backup_mmint.shCorrer el backup offsite manual (dump PROD→VPS2 + verifica + mail)
zcat $(ls -t /home/mmint/backups/*.sql.gz | head -1) | head -20Chequear que el último dump NO esté vacío/corrupto
crontab -lConfirmar que el cron de backup sigue programado

🧰 Mantenimiento · 9. Reboot seguro

pm2 savePASO 1: guardar procesos antes de reiniciar
nginx -tPASO 2: validar nginx antes (que levante limpio)
reboot⚠️ PASO 3: reinicia TODO el server (corta servicios)
pm2 ls; systemctl status nginx mysqlPASO 4 (al volver): confirmar que todo levantó
💡 Si tras el boot las apps no están: pm2 resurrect (restaura desde dump.pm2). Por eso el pm2 save previo es obligatorio.
📅 Rutina sugerida.  Diario: pm2 ls + df -h / + ojo a la tab Salud.  Semanal: revisar logs grandes + pm2 flush si pesan + certbot certificates (vencimientos) + verificar que el backup corre.  Mensual: apt update && apt upgrade en ventana (con pm2 save antes) + du de carpetas + purgar dumps viejos + mysqlcheck --optimize.
⚠️ Los comandos en VPS1 = PRODUCCIÓN. Hacé backup con fecha antes de editar, validá con node --check / nginx -t, y reiniciá solo el proceso afectado. Credenciales (DB, root) en KeePass G:\Mi unidad\Database.kdbx y la vault MMINT.