Skip to content

Self-Hosted Notification System using ntfy in a Docker

(with Example Notification for Order Received)

Notification System Diagram

uml diagram

Components

  • Shopping Cart System: Sends transaction data via webhooks.
  • Make Scenario: Processes incoming webhooks and filters transactions.
  • Ntfy Server: Hosted in a fly.io Docker container—handles receiving and sending notifications.

Order Received Identification

A filter in the Make scenario checks the transaction data bundle received from the Shopping Cart, allowing the scenario to proceed only if specified conditions are met.

Ntfy Server

  • Service URL: your-ntfy-app.fly.dev
  • Subscribe Topic: order_received
  • Full Ntfy Order Received URL: https://your-ntfy-app.fly.dev/order_received
  • User: username (read-write access to order_received topic)
  • Password: password

For more information, refer to the ntfy documentation on your server: https://your-ntfy-app.fly.dev/docs/

Setting Up Users and Permissions

To set up users and manage their permissions via the ntfy service, change to your ntfy app directory, and follow these steps in the Fly console:

  1. Access the Fly Console:

    bash
    fly ssh console -a your-ntfy-app
  2. Add a User:

    bash
    ntfy user add <username>
  3. Set User Password:

    bash
    ntfy user set-password <username> <password>
  4. Configure User Permissions:

    To grant read-write access to a topic, execute:

    bash
    ntfy user set-access <username> <topic> rw

Using ntfy Username and Password in Make Scenario

When the Make scenario's HTTP Module invokes the ntfy endpoint to publish a message to the order_received topic, it must authenticate using the ntfy username and password.

  • HTTP Request Setup:
    • URL: https://your-ntfy-app.fly.dev/order_received
    • Method: POST
    • Headers:
      • Authorization: Basic <base64_encoded_credentials>
        • The credentials are encoded in base64 format: username:password (Use an online tool for encoding a string to base64 format, such as Base64 Encode - Base64 Converter)

Deploying and Managing the Fly Machine

Navigate to your ntfy development folder, where the fly.toml file is located.

  • Deploy app:
    bash
    fly deploy
  • Start app:
    bash
    fly launch
  • Check the status of your machine(s):
    bash
    fly status
  • Monitor logs for errors or warnings:
    bash
    fly logs
  • Restart ntfy server:
    bash
    fly apps restart your-ntfy-app

Using Your ntfy Service

Via ntfy app on Android or iPhone:

  • In Settings, change Default server to https://your-ntfy-app.fly.dev
  • Add user username, password password
  • Subscribe to topic order_received
  • Set app notifications (optional)

Via browser link: https://your-ntfy-app.fly.dev:

  • Sign in as username, with password password
  • Subscribe to topic order_received
  • Set browser notifications (optional)

Note: If user username has write permission to the topic order_received, you will be able to publish messages to that topic from the client.

More info about using ntfy: https://your-ntfy-app.fly.dev/docs/ on your machine, or at ntfy.sh.

Reference: Ntfy Config

server.yml

auth-default-access: "deny-all" ensures that topics cannot be read nor published to without authentication and proper read or write authorization.

yaml
base-url: "https://your-ntfy-app.fly.dev"
listen-http: ":80"
cache-file: "/data/cache.db"
attachment-cache-dir: "/data/attachments/"
auth-file: "/data/user.db"
auth-default-access: "deny-all"

fly.toml

Note: If auto_stop_machines is true (or 'stop') and auto_start_machines is true, ensure the min_machines_running setting is not 0, as your ntfy server could stop without restarting.

toml
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'your-ntfy-app'
primary_region = 'sea'

[build]

[[mounts]]
  source = 'ntfy_data'
  destination = '/data'

[http_service]
  internal_port = 80
  force_https = true
  auto_stop_machines = 'stop'
  auto_start_machines = true
  min_machines_running = 1
  processes = ['app']

[[services]]
  protocol = 'tcp'
  internal_port = 80

  [[services.ports]]
    port = 80
    handlers = ['http']

  [[services.ports]]
    port = 443
    handlers = ['tls', 'http']

[[vm]]
  memory = '1gb'
  cpu_kind = 'shared'
  cpus = 1

Dockerfile

dockerfile
FROM binwiederhier/ntfy
COPY server.yml /etc/ntfy/server.yml
ENTRYPOINT ["ntfy", "serve"]

#Ntfy #NtfyServer #Webhooks
#Docker #FlyDev