Cuando administras tus propios servidores, tarde o temprano quieres que te avisen: que una copia de seguridad ha terminado, que un disco se está llenando o que un contenedor se ha caído. ntfy resuelve justo eso: es un servicio de notificaciones push por HTTP que te manda esos avisos al móvil o al escritorio con una simple petición curl, sin cuentas ni servicios de terceros. En esta guía levantas tu propio servidor ntfy con Docker Compose, aprendes a publicar y suscribirte a temas, a lanzar avisos desde tus scripts y otros servicios, y a protegerlo con autenticación. La misma explicación está disponible en inglés.

Puntos clave

  • ntfy (se lee "notify") es un servicio de notificaciones push por HTTP, gratuito y de código abierto con licencia dual Apache-2.0 y GPLv2, y unas 31.900 estrellas en GitHub.
  • Está escrito en Go, se distribuye como un único binario y su imagen oficial binwiederhier/ntfy incluye a la vez el servidor y el cliente de línea de comandos.
  • El servidor escucha en el puerto 80 dentro del contenedor y sirve por ahí tanto la API como la aplicación web; la última versión estable es la v2.26.0, publicada el 9 de julio de 2026.
  • Publicar un aviso es tan sencillo como una petición PUT o POST a un tema (topic): curl -d "mensaje" https://tu-ntfy/mitema. Puedes añadir título, prioridad (5 niveles, de min a urgent), etiquetas con emojis y hasta botones de acción.
  • Por defecto cualquiera puede leer y escribir en cualquier tema; con auth-default-access: deny-all y el comando ntfy user add cierras el servidor y das acceso solo a quien tú quieras.

¿Qué es ntfy y para qué sirve?

ntfy es un servicio de pub-sub (publicación y suscripción) de notificaciones basado en HTTP. Su repositorio oficial lo define como "un servicio de notificaciones pub-sub sencillo basado en HTTP". La idea es tan simple como potente: hay temas (una especie de canales identificados por un nombre), tú publicas mensajes en un tema con una petición HTTP y cualquier dispositivo suscrito a ese tema recibe el aviso al instante.

Lo que hace especial a ntfy es que publicar no requiere ninguna librería ni SDK: basta un curl desde un script de copias, un cron, una GitHub Action o cualquier programa capaz de hacer una petición HTTP. Para recibir los avisos tienes la aplicación web (que el propio servidor sirve), las apps oficiales de Android e iOS, o el cliente de línea de comandos. El servicio público ntfy.sh es gratuito, pero al autoalojarlo controlas tú los datos, evitas los límites de uso y puedes cerrar el acceso a los temas.

Frente a alternativas como Gotify, ntfy destaca por su modelo sin registro y por la riqueza de sus mensajes: prioridades, etiquetas con emojis, adjuntos, enlaces de clic y botones de acción. Es la pieza natural para recibir en el móvil los avisos de todo tu homelab, desde las actualizaciones de Watchtower hasta las alertas de un monitor como Beszel.

¿Cómo es el docker-compose.yml del servidor ntfy?

Vamos a levantar el servidor. ntfy no necesita una base de datos externa: guarda los mensajes en caché en un fichero SQLite y la lista de usuarios en otro, así que con un solo servicio y dos volúmenes basta. Crea una carpeta para el proyecto y guarda dentro este docker-compose.yml. Se fija la versión v2.26.0 en lugar de :latest, porque una etiqueta flotante puede cambiar de versión en un simple reinicio y dejarte sin control sobre lo que corres:

services:
  ntfy:
    image: binwiederhier/ntfy:v2.26.0
    container_name: ntfy
    command: serve
    restart: unless-stopped
    environment:
      TZ: Europe/Madrid
      NTFY_BASE_URL: https://ntfy.tudominio.com
      NTFY_LISTEN_HTTP: ":80"
      NTFY_BEHIND_PROXY: "true"
      NTFY_CACHE_FILE: /var/cache/ntfy/cache.db
      NTFY_CACHE_DURATION: "12h"
      NTFY_ATTACHMENT_CACHE_DIR: /var/cache/ntfy/attachments
      NTFY_AUTH_FILE: /var/lib/ntfy/user.db
      NTFY_AUTH_DEFAULT_ACCESS: deny-all
    volumes:
      - ntfy_cache:/var/cache/ntfy
      - ntfy_lib:/var/lib/ntfy
    ports:
      - "80:80"
    healthcheck:
      test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  ntfy_cache:
  ntfy_lib:

Cada variable NTFY_* equivale a una clave del fichero de configuración server.yml, así que puedes configurar todo el servidor sin montar ningún fichero. La clave más importante es NTFY_BASE_URL: debe ser la URL pública exacta por la que se accede a ntfy, porque de ella dependen los adjuntos, los enlaces de clic, el correo y las notificaciones web. El healthcheck consulta el endpoint /v1/health, que responde {"healthy":true} cuando el servidor está listo.

Arranca el servicio y comprueba que responde:

mkdir -p ntfy && cd ntfy
docker compose up -d
docker compose ps
docker compose logs -f ntfy

El servidor escucha en el puerto 80, que es el estándar de HTTP y suele estar ocupado por otro servicio. Lo recomendable es ponerlo detrás de un proxy inverso con HTTPS, como se explica en la guía de cómo instalar Traefik con Docker Compose; en ese caso deja NTFY_BEHIND_PROXY en "true" para que ntfy respete la IP real del cliente. Si solo vas a probarlo en tu red local, cambia NTFY_BASE_URL a http://IP-DEL-SERVIDOR y pon NTFY_BEHIND_PROXY en "false". Si necesitas repasar la instalación del motor, tienes la guía de cómo instalar Docker en Ubuntu 24.04.

¿Cómo publicar y suscribirse a temas?

Con el servidor en marcha, abre https://ntfy.tudominio.com en el navegador: verás la aplicación web de ntfy. Ahí puedes suscribirte a un tema escribiendo su nombre; a partir de ese momento la pestaña recibirá cualquier mensaje que se publique en él. Un tema no se crea de antemano: existe en cuanto alguien publica o se suscribe, y su nombre actúa como identificador, así que elige nombres largos y difíciles de adivinar si dejas el servidor abierto.

Publicar un mensaje es una petición HTTP normal. Desde cualquier máquina, envía texto al tema con curl:

curl -d "La copia de seguridad ha terminado" https://ntfy.tudominio.com/servidor

Ese aviso aparecerá al instante en todos los dispositivos suscritos al tema servidor. Los mensajes admiten metadatos mediante cabeceras HTTP: Title para el título, Priority para la urgencia (de min a urgent, cinco niveles en total), Tags para añadir emojis e iconos y Click para abrir una URL al pulsar la notificación:

curl \
  -H "Title: Disco casi lleno" \
  -H "Priority: urgent" \
  -H "Tags: warning,floppy_disk" \
  -d "Quedan 2 GB libres en /var" \
  https://ntfy.tudominio.com/alertas

Para recibir los avisos en el móvil, instala la app oficial de ntfy (disponible en Google Play, F-Droid y la App Store), añade la URL de tu servidor y suscríbete a los temas que te interesen. En el escritorio te sirve la propia aplicación web, y desde la terminal puedes suscribirte con el cliente incluido: ntfy subscribe alertas te muestra los mensajes en directo, e incluso puedes ejecutar un comando por cada aviso recibido.

¿Cómo enviar notificaciones desde scripts y otros servicios?

Aquí es donde ntfy brilla en un homelab. Como publicar es una simple petición HTTP, puedes engancharlo a casi cualquier cosa. En un script de shell, añade una línea al final para avisarte cuando termine una tarea larga:

restic backup /datos && curl -d "Backup nocturno correcto" https://ntfy.tudominio.com/servidor

Muchos servicios de self-hosting hablan el protocolo de notificaciones Shoutrrr, que incluye soporte nativo para ntfy con una URL del estilo ntfy://usuario:clave@ntfy.tudominio.com/mitema. Con ella, herramientas como Watchtower o Beszel pueden encaminar sus avisos directamente a tu servidor sin escribir una sola línea de código. También hay integraciones para sistemas de alertas como Prometheus Alertmanager o Grafana, y plugins para Home Assistant.

La prioridad y las etiquetas resultan clave cuando recibes muchos avisos: reserva urgent para lo que exige atención inmediata (una caída, un disco lleno) y low o min para el ruido de fondo (una copia rutinaria correcta). Así, en el móvil, los avisos críticos suenan y vibran mientras que los informativos llegan en silencio.

¿Cómo proteger ntfy con autenticación y control de acceso?

Por defecto, un servidor ntfy es abierto: cualquiera que conozca la URL puede leer y publicar en cualquier tema. Para un servidor accesible desde Internet eso no vale, y por eso en el docker-compose.yml ya pusimos NTFY_AUTH_DEFAULT_ACCESS: deny-all. Con esa opción, nadie puede leer ni escribir salvo que le des permiso explícito. El sistema de acceso se apoya en dos roles: admin, con acceso total a todos los temas, y user, cuyo acceso se define tema a tema mediante una lista de control (ACL).

Los usuarios se gestionan con el cliente ntfy dentro del propio contenedor. Crea un administrador y un usuario normal, y concédele a este último permiso de lectura y escritura sobre un tema concreto:

docker compose exec ntfy ntfy user add --role=admin phil
docker compose exec ntfy ntfy user add avisos
docker compose exec ntfy ntfy access avisos servidor rw
docker compose exec ntfy ntfy user list

A partir de ahí, para publicar hay que autenticarse. Puedes usar usuario y contraseña con curl -u avisos:laclave o, mejor, crear un token de acceso con ntfy token add avisos y enviarlo en la cabecera Authorization: Bearer <token>. Un token es más seguro porque puedes revocarlo sin cambiar la contraseña y limitarlo a un cliente concreto. Si quieres que un tema siga siendo público de lectura pero solo tú puedas escribir en él, combínalo con reglas para el usuario especial everyone, por ejemplo ntfy access everyone anuncios ro.

Preguntas frecuentes

¿Necesito una base de datos para ntfy?

No. A diferencia de otras herramientas de self-hosting, ntfy no depende de PostgreSQL ni MariaDB: guarda la caché de mensajes en un fichero SQLite (cache.db) y los usuarios y permisos en otro (user.db). Por eso el docker-compose.yml de esta guía tiene un único servicio y dos volúmenes con nombre. La caché guarda los mensajes durante 12 horas por defecto, tiempo suficiente para que un dispositivo que estuvo desconectado recupere lo que se perdió al reconectarse.

¿Funcionan las notificaciones push en iPhone con un servidor propio?

Sí, pero con un matiz. Apple solo permite push instantáneo a través de sus servidores, y la app de ntfy en la App Store está registrada contra ntfy.sh. Para recibir avisos instantáneos de tu servidor propio en iOS, configura la opción upstream-base-url: https://ntfy.sh en el servidor: entonces reenvía un aviso vacío a través de ntfy.sh para "despertar" la app, que acto seguido descarga el mensaje real de tu servidor. En Android no hace falta nada de esto y las notificaciones llegan directamente.

¿Es seguro dejar ntfy expuesto a Internet?

Solo si activas el control de acceso. Un servidor con auth-default-access: deny-all y usuarios con contraseña o token es seguro de exponer, siempre detrás de HTTPS mediante un proxy inverso. Si lo dejas abierto, cualquiera que adivine el nombre de un tema podría leer tus avisos o enviarte spam, así que como mínimo usa nombres de tema largos y aleatorios. Para uso doméstico, muchos optan por no exponerlo y acceder solo por VPN.

Conclusión

ntfy es la forma más rápida y flexible de tener notificaciones push propias en tu homelab. Con un único docker-compose.yml, sin base de datos externa, levantas un servidor que recibe avisos de cualquier script, cron o servicio con una simple petición HTTP, y los entrega al instante en tu móvil o escritorio con título, prioridad y etiquetas. El siguiente paso natural es cerrarlo con auth-default-access: deny-all y tokens, ponerlo tras un proxy con HTTPS, y encaminar hacia él los avisos de tus otras herramientas. Si prefieres un modelo con panel y aplicaciones registradas por token, compara ntfy con Gotify antes de decidir.

Fuentes

  1. Documentación oficial de ntfy: instalación
  2. Documentación de ntfy: publicar mensajes
  3. Documentación de ntfy: control de acceso
  4. Repositorio oficial de ntfy en GitHub
  5. Imagen binwiederhier/ntfy en Docker Hub

Ruta: Paneles y notificaciones self-hosted con Docker