Saltar al contenido principal

Levantar tu propio server ntfy

El plugin ntfy puede publicar contra https://ntfy.sh (el server público) o contra tu propio server. Autohospedar te da:

  • Topics privados con ACL nativa.
  • Sin límite de 250 mensajes/día por IP.
  • Ancho de banda tuyo — el server público tiene tráfico compartido.
  • Menos superficie de vigilancia — los títulos y mensajes no pasan por infraestructura de terceros.

El binary corre en cualquier Debian/Ubuntu y usa ~20 MB de RAM en idle. Este runbook cubre el setup en un LXC de Proxmox; el proceso en un VPS o en Docker es equivalente.

LXC en Proxmox​

1. Crear el container​

Desde el host Proxmox (o pct en SSH):

pct create 111 local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst \
--hostname ntfy \
--memory 256 --swap 128 --cores 1 \
--rootfs local-lvm:3 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 1 --features nesting=1 --onboot 1 \
--ssh-public-keys /root/.ssh/authorized_keys

pct start 111

Verifica que el LXC tiene IP:

pct exec 111 -- ip -4 addr show eth0 | grep inet

2. Instalar ntfy​

El repo apt oficial vive en archive.ntfy.sh. Si tu red interna no resuelve dominios externos, pon DNS público en /etc/resolv.conf antes de instalar:

pct exec 111 -- bash -c '
echo "nameserver 1.1.1.1" > /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
apt update && apt install -y curl wget
'

Descarga el .deb desde el release de GitHub (más rápido y no depende del repo apt):

NTFY_VERSION=v2.13.0
pct exec 111 -- bash -c "
wget -q https://github.com/binwiederhier/ntfy/releases/download/$NTFY_VERSION/ntfy_2.13.0_linux_amd64.deb -O /tmp/ntfy.deb
apt install -y /tmp/ntfy.deb
"

3. Configurar el server​

Edita /etc/ntfy/server.yml:

# Server config
base-url: https://ntfy.tudominio.com # el dominio público que verá el usuario
listen-http: :80
cache-file: /var/cache/ntfy/cache.db
cache-duration: 12h # cuánto guarda mensajes para suscriptores nuevos
attachment-cache-dir: /var/cache/ntfy/attachments
behind-proxy: true # ntfy corre detrás de Cloudflare Tunnel

# Authentication (opcional pero recomendado en public)
auth-file: /var/lib/ntfy/auth.db
auth-default-access: read-write # cambialo a deny-all para forzar auth
enable-signup: false
enable-login: true
enable-reservations: true # permite delay + topic ownership

# Web UI en /app
web-root: app

Ajustes de permisos y arranque:

pct exec 111 -- bash -c '
mkdir -p /var/cache/ntfy /var/lib/ntfy
chown -R ntfy:ntfy /var/cache/ntfy /var/lib/ntfy
systemctl enable --now ntfy
systemctl status ntfy --no-pager | head -8
'

4. Exponer con Cloudflare Tunnel​

Si ya tienes un tunnel corriendo, agrega una ruta que apunte al LXC. Si usas la API de Cloudflare (como en el runbook de este framework):

# Con CLOUDFLARE_API_TOKEN y CLOUDFLARE_ACCOUNT_ID exportados en el env
LXC_IP=192.168.1.41 # IP del LXC 111
TUNNEL_ID=... # el UUID de tu tunnel

# Agrega la ruta a tu ingress list (via API PUT a /cfd_tunnel/{id}/configurations)

Y crea el DNS record CNAME:

ntfy.tudominio.com CNAME <TUNNEL_ID>.cfargotunnel.com (proxied)

Verifica:

curl -sS -X POST "https://ntfy.tudominio.com/test-topic" \
-H "Title: Hola" \
-d "Server funcionando" \
-w "\nHTTP %{http_code}\n"

Debe devolver HTTP 200 y un JSON {"id":"…","event":"message",…}.

5. Conectar al framework​

En el CMS → Configuración → ntfy — notificaciones push → Configuración:

  • Servidor ntfy: https://ntfy.tudominio.com
  • Token: (opcional) el token que emitiste con ntfy user add ….
  • Prefijo: si compartís el server con varias instalaciones, pon un prefijo (empresa-, cliente-) para evitar colisiones.

Y en el config.php del plugin agrega tu host al allowlist:

return [
'extra_hosts' => ['ntfy.tudominio.com'],
// o bien:
'extra_suffixes' => ['.tudominio.com'],
];

Esto abre el guard NtfyEngine::isTrustedServerUrl para tu host — sin esta línea el conector se niega a publicar (protege contra SSRF).

Configuración con Docker​

Alternativa sin Proxmox:

docker run -d --name ntfy \
-p 80:80 \
-v ntfy-cache:/var/cache/ntfy \
-v ntfy-lib:/var/lib/ntfy \
-e TZ=America/Santiago \
binwiederhier/ntfy serve

Después el mismo tunnel/DNS/firewall.

Users y ACL​

Con auth-default-access: deny-all en el yaml, los suscriptores y publishers necesitan credenciales:

# Crear un admin
ntfy user add --role=admin admin

# Crear un usuario publisher (sólo escribe)
ntfy user add publisher-aurora
ntfy access publisher-aurora aurora-* write-only

# Crear un usuario reader (sólo lee un topic específico)
ntfy user add cliente-42
ntfy access cliente-42 aurora-cliente-42 read-only

El framework usa las credenciales del admin (token) para publicar. El subscriber final entra con su propia credencial o suscribe a un topic público (sin auth).

Backup​

Los datos viven en:

  • /var/cache/ntfy/ (mensajes en cache, se puede perder)
  • /var/lib/ntfy/ (auth.db, ACL, reservations — esto sí backup)

Backup diario del segundo directorio con tar o el mecanismo que uses para el resto del stack.

Monitoreo​

ntfy expone metrics en /metrics (formato Prometheus) si activas enable-metrics: true. Útil para trackear publish rate y suscriptores activos.

¿Qué sigue?​

  • Plugin ntfy — para crear topics y ver la actividad desde el CMS.
  • Notification Manager — para disparar ntfy con reglas visuales sobre transiciones de workflow.