[{"data":1,"prerenderedAt":188},["ShallowReactive",2],{"seo-verification":3,"blog-autoalojar-ntfy-en-un-vps-ma-es":6,"promo-bar-likely":187},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-autoalojar-ntfy-en-un-vps-ma-es",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":33,"intro":36,"sections":37,"ctaTitle":124,"ctaBody":125,"ctaButton":126,"ctaUrl":127,"relatedPosts":128},194,"autoalojar-ntfy-en-un-vps",{"fr":12,"en":13,"ar":14,"es":10},"self-host-ntfy-vps","self-host-ntfy-on-a-vps-push-notifications-for-scripts-and-cicd","استضافة-ntfy-على-vps-إشعارات-فورية-من-سكريبتاتك-وcicd","Alojar ntfy en un VPS: notificaciones push para sus scripts","Despliegue ntfy en su VPS y envíe notificaciones push desde cualquier script, cron o pipeline CI\u002FCD con un simple curl — sin SaaS ni clave de API.",16,2,false,"2026-07-28T00:00:00+00:00","2026-11-04T16:30:26+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Seguridad y monitorización","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-ntfy-vps-poster.svg",{"categorySlug":34,"appSlug":35},"monitorizacion-observabilidad","ntfy","Slack se paga por asiento. Los correos se pierden en el ruido. Los webhooks de Discord desaparecen en un hilo. ntfy (Apache 2.0, ~32 k ⭐, v2.30.0 — oct. 2026) resuelve el problema de otra manera: un servidor pub\u002Fsub HTTP que usted mismo aloja en su VPS y al que cualquier script envía una alerta con un `curl -d`. La aplicación móvil recibe el push en tiempo real — incluso fuera de la red local. Un solo contenedor Docker, \u003C 30 MB de RAM, sin cuenta de terceros. En este artículo: despliegue, autenticación, configuración multi-tenant con `server.yml`, integraciones con Backrest \u002F Uptime Kuma \u002F cron, notificaciones SMTP y los cinco errores reales que todo administrador se encuentra en producción.",[38,42,55,58,86,89,92,96,99,102,112,115,118,121],{"type":39,"title":40,"body":41},"h2","El problema: demasiadas herramientas de monitoreo, demasiados canales de notificación","Uptime Kuma vigila sus servicios, Beszel vigila las métricas de su VPS, Backrest gestiona sus copias de seguridad, y sus cron jobs callan por la noche — salvo cuando fallan. Cada uno tiene su canal de notificación: Slack, correo, webhook, Telegram. Resultado: cinco integraciones distintas que mantener, cinco tipos de alerta que formatear y ninguna vista unificada cuando algo falla a las 03:00. ntfy resuelve el problema al revés: es usted quien aloja el hub de notificaciones, y cada herramienta o script le envía sus alertas por HTTP puro.",{"type":43,"title":44,"items":45},"ul","Lo que ntfy aporta de entrada",[46,47,48,49,50,51,52,53,54],"Envío de una notificación con un simple curl — `curl -d \"Build fallido\" https:\u002F\u002Fntfy.ejemplo.com\u002Falertas-ci` — cero SDK, cero bibliotecas.","Recepción en Android (F-Droid \u002F Play Store), iOS (App Store), navegador de escritorio e interfaz web de ntfy — todos se suscriben al mismo topic vía WebSocket o SSE.","Acciones dentro de la notificación — botones que disparan callbacks HTTP, abren URL o ejecutan comandos en el dispositivo.","Notificaciones programadas — entrega diferida (`X-Delay: 30min`) para programar recordatorios desde sus scripts.","Niveles de prioridad (mín. \u002F baja \u002F predeterminada \u002F alta \u002F urgente) con anulación del modo No molestar para las alertas críticas.","Archivos adjuntos — imágenes o archivos de hasta 15 MB mediante la cabecera `X-Attach` o una subida multipart.","Notificaciones SMTP — ntfy puede enviar un correo de respaldo si su móvil está desconectado o la app no está instalada.","Control de acceso granular — usuarios, contraseñas cifradas con bcrypt, tokens de acceso y ACL por topic.","\u003C 30 MB de RAM, SQLite, un solo contenedor — el servidor de notificaciones push más ligero de su categoría.",{"type":39,"title":56,"body":57},"Arquitectura: un pub\u002Fsub HTTP en un solo contenedor","ntfy es un binario Go que cabe en un único contenedor Docker. Expone una interfaz HTTP sencilla: un `PUT` o un `POST` sobre `\u002Fsu-topic` publica un mensaje; cualquier cliente que escuche ese topic lo recibe al instante. Los mensajes se guardan en caché en SQLite con una retención configurable (12 horas por defecto). En producción, ntfy se coloca detrás de un proxy inverso nginx que gestiona el TLS — `behind-proxy: true` en `server.yml` indica a ntfy que lea la IP real desde `X-Forwarded-For`. Toda la configuración avanzada vive en un único archivo `\u002Fetc\u002Fntfy\u002Fserver.yml`.",{"type":59,"title":60,"steps":61},"steps","Desplegar ntfy en producción: 8 pasos",[62,65,68,71,74,77,80,83],{"title":63,"body":64},"Desplegar ntfy desde el marketplace ServOrbit","Abra su panel de ServOrbit → Marketplace → Monitoring → ntfy → Desplegar. Docker descarga `binwiederhier\u002Fntfy:v2.30.0`, arranca ntfy en el puerto 8080 y la interfaz web queda accesible en menos de 5 segundos con un certificado Let's Encrypt en su dominio.",{"title":66,"body":67},"Enviar su primera notificación","Desde cualquier terminal con curl:\n`curl -d \"Hola desde mi VPS\" https:\u002F\u002Fntfy.ejemplo.com\u002Fmi-topic`\nAbra la interfaz web de ntfy, vaya a `mi-topic` y su mensaje aparece en tiempo real.",{"title":69,"body":70},"Crear el server.yml completo","Monte un archivo de configuración en el contenedor:\n`base-url: https:\u002F\u002Fntfy.ejemplo.com`\n`listen-http: \":8080\"`\n`behind-proxy: true`\n`cache-file: \u002Fvar\u002Flib\u002Fntfy\u002Fcache.db`\n`cache-duration: 12h`\n`auth-file: \u002Fvar\u002Flib\u002Fntfy\u002Fuser.db`\n`auth-default-access: deny-all`\n`smtp-sender-addr: smtp.ejemplo.com:587`\n`smtp-sender-user: notificaciones@ejemplo.com`\n`smtp-sender-pass: contraseñaSMTP`\n`smtp-sender-from: notificaciones@ejemplo.com`\nReinicie el contenedor tras cualquier cambio: `docker restart ntfy`.\nPara recibir notificaciones también en iOS, añada `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"` a este archivo: la sección «iOS» más abajo explica por qué.",{"title":72,"body":73},"Crear usuarios y tokens de acceso","# Crear un usuario admin interactivo\n`docker exec -it ntfy ntfy user add --role=admin admin`\n# Crear un usuario para scripts\n`docker exec -it ntfy ntfy user add scripts`\n# Generar un token de acceso\n`docker exec -it ntfy ntfy token add scripts`\n# Salida: tk_AbCdEf123456...\n# Conceder lectura\u002Fescritura sobre un topic\n`docker exec -it ntfy ntfy access scripts server-alerts rw`",{"title":75,"body":76},"Suscribirse desde su teléfono con autenticación","Instale la app ntfy (Android: F-Droid o Play Store; iOS: App Store). Pulse + → introduzca la URL del servidor y el topic. Cuando ntfy solicite credenciales, introduzca el nombre de usuario y la contraseña. Recibirá push mediante UnifiedPush, FCM o APNs. En iOS, el push instantáneo solo llega si su servidor tiene `upstream-base-url` definido (vea la sección dedicada más abajo).",{"title":78,"body":79},"Alertar desde cron jobs usando un token","#!\u002Fbin\u002Fbash\n`NTFY_URL=\"https:\u002F\u002Fntfy.ejemplo.com\"`\n`NTFY_TOKEN=\"tk_AbCdEf123456\"`\n`\u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh; STATUS=$?`\n`if [ $STATUS -eq 0 ]; then`\n`curl -s -H \"Authorization: Bearer $NTFY_TOKEN\"        -H \"Title: Backup nocturno\" -H \"Priority: default\"        -d \"Backup completado a las $(date)\" \"$NTFY_URL\u002Fcron-jobs\"`\n`else`\n`curl -s -H \"Authorization: Bearer $NTFY_TOKEN\"        -H \"Title: Backup FALLIDO\" -H \"Priority: urgent\"        -d \"Backup fallido — código $STATUS\" \"$NTFY_URL\u002Fcron-jobs\"`\n`fi`",{"title":81,"body":82},"Configurar Backrest y Uptime Kuma","**Backrest**: UI → Planes → su plan → Hooks → Añadir Hook → tipo `Webhook (ntfy)` → URL del topic y token Bearer.\n\n**Uptime Kuma**: Ajustes → Notificaciones → Nuevo → tipo `ntfy` → URL del servidor → topic `server-alerts` → usuario\u002Fcontraseña. Pruebe la notificación desde la UI.\n\n**Grafana**: Contact point → webhook → URL `https:\u002F\u002Fntfy.ejemplo.com\u002Fgrafana` → cabeceras `Authorization: Bearer tk_...` y `Content-Type: text\u002Fplain`.",{"title":84,"body":85},"Activar notificaciones de correo de respaldo (SMTP)","Una vez configurado `smtp-sender-addr` en `server.yml`, envíe una notificación con la cabecera `X-Email`:\n`curl -H \"Authorization: Bearer $NTFY_TOKEN\"      -H \"Title: Alerta crítica\"      -H \"X-Email: usted@ejemplo.com\"      -d \"Disco lleno al 95%\"      https:\u002F\u002Fntfy.ejemplo.com\u002Fserver-alerts`\nntfy envía el push Y el correo electrónico.",{"type":39,"title":87,"body":88},"Autenticación y tokens de acceso: nunca exponga un topic público","Sin configuración, ntfy arranca sin control de acceso (la doc indica `auth-default-access` en `read-write`) — cualquiera que conozca la URL puede leer y escribir. En producción: `auth-default-access: deny-all` cierra el servidor; usuarios con contraseñas bcrypt en `user.db`; tokens de acceso vinculados a un usuario específico y revocables de forma independiente. Un token comprometido se revoca sin cambiar la contraseña del usuario.",{"type":39,"title":90,"body":91},"Configuración multi-tenant: un servidor, varios equipos","Cree un usuario por servicio o equipo, concédale derechos solo sobre sus topics, y cada servicio creerá tener su propio hub. El rol `admin` ve todo; los usuarios normales están limitados a sus ACL. Para equipos con aislamiento total, despliegue dos contenedores ntfy en dos subdominios distintos.",{"type":93,"title":94,"body":95},"tip","Consejo: los nombres de topic como espacios de nombres y estrategia de silencio nocturno","`ci-builds` para GitHub Actions\u002FGitLab CI, `server-alerts` para Uptime Kuma\u002FBeszel, `cron-jobs` para scripts por lotes, `backups` para Backrest. La app ntfy le permite silenciar ciertos topics por la noche mientras mantiene `server-alerts` en alerta máxima con anulación de No molestar.",{"type":39,"title":97,"body":98},"Resolución de problemas: 5 errores reales en producción","**1. `HTTP 403 Forbidden` al publicar o suscribirse**\nMensaje: `{\"code\":40301,\"http\":403,\"error\":\"Unauthorized\"}`\nCausa: `auth-default-access: deny-all` activo y el token falta o ha caducado. Regenere el token con `ntfy token add \u003Cusuario>` y actualice sus scripts.\n\n**2. Notificación enviada pero nunca recibida en el móvil**\nEn Android, compruebe primero que la app está suscrita a su instancia y no al servidor público `ntfy.sh` (URL en los ajustes de la app). En iOS, la causa más probable es la ausencia de `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"` en `server.yml`: sin ese relé, la doc advierte de que la entrega puede tardar horas. Configúrelo y repase la checklist de la sección iOS más abajo. `base-url` también debe estar definido, pero la doc lo asocia a las URL de adjuntos y al pie de los correos, no a la llegada del push.\n\n**3. Enlaces incorrectos en los correos salientes**\nSin `base-url`, el pie del correo (enlace a la notificación) se construye sin la URL pública y no sirve desde el exterior. Solución: establecer `base-url: https:\u002F\u002Fntfy.ejemplo.com` y reiniciar el contenedor.\n\n**4. Caídas repetidas de WebSocket en producción (reconexiones cada 30 s)**\nCausa: el timeout keepalive de nginx es inferior al intervalo de heartbeat de ntfy (`keepalive-interval: \"45s\"` en la configuración de ejemplo de la doc). Añada `proxy_read_timeout 60;` y `proxy_send_timeout 60;` al bloque `location`. Verifique también `proxy_http_version 1.1;` y `proxy_set_header Upgrade $http_upgrade;`.\n\n**5. OOM (Out of Memory) en un topic de alto volumen**\nReduzca `cache-duration` a `1h` o `30m`. Filtre en el script (`| grep -E 'ERROR|WARN'`) para enviar solo eventos relevantes. ntfy puede usar PostgreSQL en lugar de SQLite para sus almacenes (vea la doc de configuración).",{"type":39,"title":100,"body":101},"iOS: por qué un ntfy autoalojado pasa por ntfy.sh para el push","En iOS una app no puede mantener una conexión abierta en segundo plano: la documentación de ntfy explica que esta restricción hace imposible un push instantáneo sin un servidor central. Su servidor autoalojado reenvía por tanto, por cada mensaje, una petición de «poll» a un servidor ascendente, `ntfy.sh` por defecto, que se encarga de despertar la app. El ajuste es `upstream-base-url: \"https:\u002F\u002Fntfy.sh\"`. Esa petición solo contiene el identificador del mensaje (cabecera `X-Poll-ID`) y el hash SHA-256 de la URL del topic, nunca el texto: el servidor autoalojado envía literalmente «New message» y la app va a buscar el contenido real a su servidor. Sin `upstream-base-url`, la documentación advierte de que las notificaciones acaban llegando, pero la entrega puede tardar horas (20 a 30 minutos si el teléfono se usa activamente). `upstream-access-token` es opcional: la doc solo lo reserva para cuando se superan los límites del servidor ascendente o este está protegido.",{"type":43,"title":103,"items":104},"Checklist iOS: siete comprobaciones antes de buscar más lejos",[105,106,107,108,109,110,111],"**`base-url`** — definido con la URL pública en HTTPS de su servidor, la que el teléfono puede alcanzar.","**`upstream-base-url`** — presente en `server.yml` (o como variable de entorno), valor `https:\u002F\u002Fntfy.sh`, contenedor reiniciado.","**Servidor por defecto de la app** — en los ajustes de la app iOS, la URL de su servidor es la declarada como servidor por defecto.","**Suscripción al servidor correcto** — el topic se añadió eligiendo su servidor, no `ntfy.sh`: un topic con el mismo nombre en el servidor público es otro topic.","**Token ascendente** — `upstream-access-token` solo sirve si se alcanzan los límites del relé; sin causa establecida, no lo añada por reflejo esperando arreglar el problema.","**Registros del servidor** — compruebe que el mensaje se publica y luego se transmite al relé. Si es así, su lado funciona y el problema está entre el relé, Apple y el teléfono.","**Ajustes del teléfono** — Actualización en segundo plano y Notificaciones activadas para la app, y ningún bloqueador DNS (AdGuard Home, Pi-hole) que filtre `ntfy.sh`.",{"type":39,"title":113,"body":114},"Cuando no llega nada pese a todo: lo que dicen realmente las issues #1305 y #1844","Estas dos issues del repositorio de ntfy describen el síntoma que busca: un servidor autoalojado, un push iOS que no aparece, mensajes que solo aparecen al refrescar la app a mano. Leídas el 30 de octubre de 2026, ambas están abiertas y ninguna señala una causa confirmada.\n\n**#1305 «No push notifications on ios?»** (abierta en marzo de 2025, etiquetas ios y bug). El autor no recibe ningún aviso, ni con ntfy.sh ni con su propia instancia. Algunos comentarios dicen que reinstalar la app ayudó, otros que el problema volvió meses después. Un colaborador propone que la app se reabone a los topics de Firebase al arrancar y abrió una PR en borrador, precisando que no pudo probarla. Un mantenedor pregunta al autor si la suscripción de Firebase es la causa, sin concluir.\n\n**#1844 «No iOS Push notification, also with valid subscription»** (abierta en julio de 2026, etiquetas ios, server y bug). El autor ejecuta ntfy en Docker con `NTFY_UPSTREAM_BASE_URL` en `https:\u002F\u002Fntfy.sh` y `NTFY_UPSTREAM_ACCESS_TOKEN` informado. Dice haber alcanzado el límite gratuito de 250 mensajes al día y haber contratado después una suscripción de pago. Sus registros muestran el mensaje publicado y enviado al relé, y aun así ningún push. Un colaborador responde que los errores 429 pueden suponer un bloqueo de IP de hasta 4 horas, constata que la prueba con `curl` del autor funciona (por tanto no hay bloqueo) y que la cuenta mostraba 48 mensajes enviados de 2 500. Añade que las notificaciones iOS son caprichosas sin que se sepa exactamente por qué. Solución alternativa comunicada: desactivar y volver a activar «Actualización en segundo plano» y «Notificaciones» en los ajustes de iOS. El autor escribe que no sabe por qué funciona; el problema volvió, luego desapareció sin causa conocida, y otro usuario confirma la solución en septiembre de 2026. Otro informe relaciona un caso parecido con listas de bloqueo DNS.\n\n**Lo que se puede concluir y lo que no.** Ni un límite diario de mensajes ni un bloqueo 429 quedan establecidos como causa en estos hilos: el 429 se descarta para la IP del autor, y el límite de 250 mensajes es una cifra dada por él, no por la documentación de configuración. El token ascendente no resuelve ahí el problema. Trate la lista anterior como comprobaciones, no como una corrección garantizada.",{"type":93,"title":116,"body":117},"Tip: no confíe una alerta crítica solo al push de iOS","Mientras estas issues sigan abiertas, duplique las alertas que importan: añada la cabecera `X-Email` (vea el paso SMTP) para recibir también un correo, o mantenga un segundo canal en el teléfono. Los colaboradores de ambas issues sugieren además la PWA (web push) como alternativa a la app iOS. Y pruebe de extremo a extremo tras cada actualización de la app o de iOS, con el heartbeat del watchdog descrito más arriba.",{"type":39,"title":119,"body":120},"Integraciones avanzadas: Backrest, Uptime Kuma, Grafana","**Backrest** soporta ntfy de forma nativa: configure la URL del topic y el token Bearer en la UI de Backrest, y cada snapshot completada o fallida genera automáticamente una notificación push con el nombre de la snapshot, el tamaño deduplicado y la duración. Cero scripts, cero cron.\n\n**Uptime Kuma** soporta ntfy de forma nativa en su gestor de notificaciones. Cada monitor puede tener múltiples canales — combine ntfy para el push móvil y el SMTP de ntfy para la trazabilidad.\n\n**Grafana** usa webhooks genéricos. Cree un contact point de tipo `webhook`, apúntelo a `https:\u002F\u002Fntfy.ejemplo.com\u002Fgrafana`, añada las cabeceras `Authorization: Bearer tk_...` y `Content-Type: text\u002Fplain`.",{"type":93,"title":122,"body":123},"Consejo: pruebe la cadena de entrega de extremo a extremo antes de confiar en ella","Antes de conectar su infraestructura a ntfy, pruebe la cadena completa: envíe una notificación con `curl`, confirme que aparece en la interfaz web, que llega a la app móvil, y que el correo SMTP de respaldo aterriza en la bandeja de entrada. Programe un cron `*\u002F30 * * * *` que envíe un heartbeat al topic `watchdog` — si la app móvil no lo recibe en 30 minutos, ntfy en sí mismo está caído.","Su hub de notificaciones bajo su control","Despliegue ntfy en un VPS ServOrbit y centralice todas sus alertas de monitoreo, CI\u002FCD y cron en un hub de notificaciones autoalojado — sin SaaS, sin suscripción.","Desplegar ntfy","\u002Fapplications\u002Fmonitorizacion-observabilidad\u002Fntfy",[129,146,169],{"id":130,"slug":131,"slugs":132,"title":136,"excerpt":137,"readTime":23,"views":18,"isPinned":19,"noindex":19,"publishedAt":138,"updatedAt":139,"category":140,"categories":141,"featuredImage":30,"bgImage":31,"posterImage":143,"relatedSolution":144},133,"alojar-beszel-hub-monitorizacion-vps",{"fr":133,"en":134,"ar":135,"es":131},"self-host-beszel-vps","self-host-beszel-multi-server-monitoring-hub-on-your-vps","استضف-beszel-على-vps-مركز-مراقبة-متعدد-الخوادم","Beszel en VPS: monitorización multiservidor, alertas y seguridad","Supervise su parque de VPS desde un único hub Beszel: alertas por Telegram y correo, 2FA, agentes declarados automáticamente y solución de conexiones silenciosas.","2026-02-14T00:00:00+00:00","2026-11-04T16:30:25+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[142],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fself-host-beszel-vps-poster.svg",{"categorySlug":34,"appSlug":145},"beszel",{"id":147,"slug":148,"slugs":149,"title":153,"excerpt":154,"readTime":155,"views":18,"isPinned":19,"noindex":19,"publishedAt":156,"updatedAt":157,"category":158,"categories":164,"featuredImage":30,"bgImage":31,"posterImage":166,"relatedSolution":167},167,"alojar-dozzle-en-un-vps",{"fr":150,"en":151,"ar":152,"es":148},"self-host-dozzle-vps","how-to-self-host-dozzle-on-a-vps-real-time-docker-log-viewer","استضافة-dozzle-على-vps-عارض-سجلات-docker-لحظيا","Alojar Dozzle en un VPS: logs Docker en tiempo real","Despliegue Dozzle en su VPS: un visor de logs Docker open source y sin estado. Siga y busque en directo los logs de sus contenedores, sin SSH.",4,"2026-07-06T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},7,"Autoalojamiento","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[165],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fself-host-dozzle-vps-poster.svg",{"categorySlug":34,"appSlug":168},"dozzle",{"id":170,"slug":171,"slugs":172,"title":176,"excerpt":177,"readTime":178,"views":179,"isPinned":19,"noindex":19,"publishedAt":180,"updatedAt":157,"category":181,"categories":182,"featuredImage":30,"bgImage":31,"posterImage":184,"relatedSolution":185},182,"alojar-changedetection-io-en-un-vps",{"fr":173,"en":174,"ar":175,"es":171},"self-host-changedetection-vps","self-host-changedetectionio-on-a-vps-monitor-any-website","استضافة-changedetectionio-على-vps-مراقبة-تغييرات-المواقع","Changedetection.io en VPS: monitoriza cambios en sitios web","Changedetection.io en VPS: detección open source, filtros CSS\u002FXPath, 80+ canales de notificación. Regresiones v0.60.x documentadas.",9,0,"2026-07-17T00:00:00+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},[183],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fself-host-changedetection-vps-poster.svg",{"categorySlug":34,"appSlug":186},"changedetection",true,1794270555596]