feat: add ntfy notification system

This commit is contained in:
Clément Désiles
2025-12-15 23:09:47 +01:00
parent 150a032988
commit d8eb53f096
9 changed files with 450 additions and 0 deletions
@@ -0,0 +1,23 @@
---
services:
ntfy:
container_name: ntfy
image: {{ ntfy_image }}:{{ ntfy_version }}
command:
- serve
volumes:
- /etc/localtime:/etc/localtime:ro
- {{ podman_projects_dir }}/ntfy/server.yml:/etc/ntfy/server.yml:ro
- {{ ntfy_cache_dir }}:/var/cache/ntfy:rw,Z
- {{ ntfy_data_dir }}:/var/lib/ntfy:rw,Z
ports:
- "{{ ntfy_port }}:80"
restart: always
healthcheck:
test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
environment:
TZ: {{ ntfy_timezone }}
+60
View File
@@ -0,0 +1,60 @@
# Ntfy vhost with Let's Encrypt (Certbot)
# Managed by Ansible - DO NOT EDIT MANUALLY
server {
listen 80;
server_name {{ ntfy_nginx_hostname }};
# Certbot webroot for ACME challenges
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# Redirect to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
server_name {{ ntfy_nginx_hostname }};
# Let's Encrypt certificates (managed by Certbot)
ssl_certificate /etc/letsencrypt/live/{{ ntfy_nginx_hostname }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ ntfy_nginx_hostname }}/privkey.pem;
# SSL configuration
ssl_protocols {{ nginx_ssl_protocols }};
ssl_prefer_server_ciphers {{ 'on' if nginx_ssl_prefer_server_ciphers else 'off' }};
{% if nginx_log_backend == 'journald' %}
access_log syslog:server=unix:/dev/log,nohostname,tag=nginx_ntfy;
error_log syslog:server=unix:/dev/log,nohostname,tag=nginx_ntfy;
{% else %}
access_log /var/log/nginx/{{ ntfy_nginx_hostname }}_access.log main;
error_log /var/log/nginx/{{ ntfy_nginx_hostname }}_error.log;
{% endif %}
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:{{ ntfy_port }};
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket and SSE support for ntfy
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Buffering must be off for SSE (Server-Sent Events)
proxy_buffering off;
# Timeouts for long-polling connections
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
+16
View File
@@ -0,0 +1,16 @@
[Unit]
Description=Ntfy Notification Service
Requires=network-online.target
After=network-online.target
[Service]
Type=oneshot
RemainAfterExit=true
WorkingDirectory={{ podman_projects_dir }}/ntfy
ExecStart=/usr/bin/podman compose up -d
ExecStop=/usr/bin/podman compose down
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
+65
View File
@@ -0,0 +1,65 @@
# Ntfy server configuration
# Managed by Ansible - DO NOT EDIT MANUALLY
# Public facing base URL of the service (e.g. https://ntfy.sh)
base-url: "{{ ntfy_base_url }}"
# Listen address for the HTTP & HTTPS web server. If "listen-https" is set, you must also
# set "key-file" and "cert-file". Format: [<ip>]:<port>, e.g. "1.2.3.4:8080".
listen-http: ":80"
# If set, also publish messages to a Firebase Cloud Messaging (FCM) topic for your app.
# This is optional and only required to support Android apps (which don't allow background
# tasks anymore). See https://ntfy.sh/docs/config/ for details.
# upstream-base-url: "https://ntfy.sh"
# Path to the private database file. If unset, the database is in memory.
cache-file: "/var/cache/ntfy/cache.db"
# Path to the attachment cache directory. Attachments are only stored if this is set.
attachment-cache-dir: "/var/cache/ntfy/attachments"
# If set, access tokens will be stored in this file. If unset, tokens are in-memory only.
auth-file: "/var/lib/ntfy/user.db"
# Default access level for new topics. Can be "read-write", "read-only", "write-only" or "deny-all".
# If "deny-all", no access is allowed by default and explicit ACLs must be configured.
auth-default-access: "deny-all"
# If enabled, allows users to sign up via the web app or API
enable-signup: {{ 'true' if ntfy_enable_signup else 'false' }}
# If enabled, allows users to log in via the web app or API
enable-login: {{ 'true' if ntfy_enable_login else 'false' }}
# If enabled, allows users to reserve topics via the web app or API (requires authentication)
enable-reservations: {{ 'true' if ntfy_enable_reservations else 'false' }}
# If set, the X-Forwarded-For header will be used to determine the visitor IP
behind-proxy: {{ 'true' if ntfy_behind_proxy else 'false' }}
# Interval in which keepalive messages are sent to the client. This is to prevent
# intermediaries from closing the connection for inactivity.
keepalive-interval: "45s"
# Interval in which the manager prunes old messages, deletes old attachments, and
# resets rate limiters. Note that these tasks are only executed if the interval has passed AND
# if there is traffic on the server.
manager-interval: "1m"
# Allowed origins for web app (CORS). Defaults to "*", which is fine for most cases.
# web-root: "/"
# Rate limiting: Number of requests allowed per visitor
visitor-request-limit-burst: 60
visitor-request-limit-replenish: "5s"
# Size limits
message-size-limit: "4096"
attachment-file-size-limit: "15M"
attachment-total-size-limit: "5G"
attachment-expiry-duration: "3h"
# Visitor limits
visitor-attachment-total-size-limit: "100M"
visitor-attachment-daily-bandwidth-limit: "500M"