Instant push notifications if email feels old timey and crowded
- gotify - great for a single person use, but the moment theres more people they need to share a single account and so lack the ability to choose what to get and what not to get.
- ntfy - simple original approach to just subscribing to "topics". Single line of code to send a push notification. Support for multiple users, supports ios.
- signal-cli-rest-api - no gui, needs a sim card, a phone number registred, notifications are send through that phone number. Signal's wider spread might make it a winner, since you are not asking people to install an another app.
Afte few weeks of tinkering with these... ntfy is the winner for me, for now.
Compose files for the other two are at the end.
docker-compose.yml
services:
ntfy:
image: binwiederhier/ntfy
container_name: ntfy
hostname: ntfy
env_file: .env
restart: unless-stopped
command:
- serve
ports:
- "80:80"
volumes:
- ./ntfy_cache:/var/cache/ntfy
- ./ntfy_etc:/etc/ntfy
networks:
default:
name: $DOCKER_MY_NETWORK
external: true
.env
# GENERAL
DOCKER_MY_NETWORK=caddy_net
TZ=Europe/Bratislava
Caddy is used, details
here.
Caddyfile
ntfy.{$MY_DOMAIN} {
reverse_proxy ntfy:80
}
ntfy uses "topics" for categorization, which creates a very handy disconnect from
sender and receiver.
Lets say there's a minecraft server and there are notifications when someone
joins. These notifications are send to minecraft
topic, not to specified users.
Users can subscribe to the topic if they want those notifications.
This gives great flexibility and is the main reason why ntfy wins
over other solutions. In this setup there is also no authentification.
curl -d "a player joined" https://ntfy.example.com/minecraft
-
win10+
Invoke-RestMethod -Method 'Post' -Uri https://ntfy.example.com/minecraft -Body "a player joined" -UseBasicParsing
-
win8.1 and older need bit extra for https to work
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 Invoke-RestMethod -Method 'Post' -Uri https://ntfy.example.com/minecraft -Body "a player joined" -UseBasicParsing
To allows use of ntfy OnFailure
and OnSuccess
inside systemd unit files.
To send useful info specifiers are used.
- %n - full unit name
- %p - prefix part of the name
- %i - instance name, between @ and suffix
- %H - machine hostname
Systemd template unit file is used.
These contains @
to allow for dynamical naming at runtime.
They are called with additional info added between @
and the suffix .service
[Unit]
Description=ntfy notification service
After=network.target
[Service]
Type=simple
ExecStart=/bin/curl -d "%i | %H" https://ntfy.example.com/systemd
Example of a service using the above defined service to send notifications.
borg.service
[Unit]
Description=BorgBackup docker
OnFailure=ntfy@failure-%p.service
OnSuccess=ntfy@success-%p.service
[Service]
Type=simple
ExecStart=/opt/borg_backup.sh
Alerting in grafana to ntfy works, but its ugly with just json shown.
To solve this
- Add container grafana-to-ntfy.
Set in
.env
ntfy local url - in grafana set contact point webhook aimed at
http://grafana-to-ntfy:8080
, with credentials from the.env
docker-compose.yml
services:
ntfy:
image: binwiederhier/ntfy:v2.4.0
container_name: ntfy
hostname: ntfy
env_file: .env
restart: unless-stopped
command:
- serve
ports:
- "80:80"
volumes:
- ./ntfy_cache:/var/cache/ntfy
- ./ntfy_etc:/etc/ntfy
grafana-to-ntfy:
container_name: grafana-to-ntfy
hostname: grafana-to-ntfy
image: kittyandrew/grafana-to-ntfy
restart: unless-stopped
env_file:
- .env
ports:
- "8080:8080"
networks:
default:
name: $DOCKER_MY_NETWORK
external: true
.env
# GENERAL
DOCKER_MY_NETWORK=caddy_net
TZ=Europe/Bratislava
NTFY_URL=http://ntfy:80/whatever
BAUTH_USER=admin
BAUTH_PASS=test
gotify-docker-compose.yml
services:
gotify:
image: gotify/server
container_name: gotify
hostname: gotify
restart: unless-stopped
env_file: .env
volumes:
- "./gotify_data:/app/data"
networks:
default:
name: caddy_net
external: true
signal-docker-compose.yml
signal:
image: bbernhard/signal-cli-rest-api
container_name: signal
hostname: signal
env_file: .env
restart: unless-stopped
volumes:
- "./signal-cli-config:/home/.local/share/signal-cli" #map "signal-cli-config" folder on host system into docker container. the folder contains the password and cryptographic keys when a new number is registered
networks:
default:
name: caddy_net
external: true