Skip to main content

Deployment

Deploy Reverse Proxy for ntfy to Cloudflare Workers and configure DNS, SSL, and custom domain routes.

Cloudflare Requirements

  • Cloudflare account — Free or paid. The deployment uses Workers and SQLite-backed Durable Objects; current plan limits and pricing apply.
  • Registered domain — You need a domain managed by Cloudflare DNS. Cloudflare Registrar offers domains at cost with no markup.
  • Cloudflare API token — Deploy uses a Cloudflare API token with the permissions listed below, both for its own Cloudflare calls and to run Wrangler (Cloudflare's deployment CLI). It reads CLOUDFLARE_API_TOKEN from your environment or .env file, and Deploy in the interactive menu walks you through creating one.

How Deployment Works

The deploy command runs these steps in sequence:

  1. Resolve API token — Reads CLOUDFLARE_API_TOKEN from the environment or .env. If it's missing or invalid, Deploy in the interactive menu prompts for a new one and saves it, while nrp deploy stops with an error.
  2. Validate — Checks config integrity (schema, server references, duplicate IDs).
  3. Verify permissions — Confirms the API token has access to Workers Scripts, Workers Routes, Workers KV Storage, and (if email contexts exist) Email Routing Rules.
  4. Ensure KV namespace — Creates or locates a Cloudflare Workers KV namespace for Statuspage deduplication. The namespace ID is automatically passed to the wrangler.toml generator.
  5. Generate — Produces wrangler.toml next to your config.json with all routes and bindings, plus a copy of your config in .wrangler/ntfy-reverse-proxy/ beside it that ships inside the worker.
  6. Deploy worker — Invokes wrangler deploy to push the worker to Cloudflare.
  7. Setup email routing — If email contexts exist, automatically configures Cloudflare Email Routing rules to forward emails to the worker.
  8. Print summary — Displays deployed context URLs and email addresses.

Generated wrangler.toml

The generated file includes:

  • Routes — Each HTTP context gets a custom domain route: {context-id}.{base_domain}. Cloudflare automatically creates DNS records for custom domain routes.
  • Email routing — Comments showing which email addresses need to be configured in Cloudflare Email Routing for email contexts.
  • Bundled config — main points to a generated entry in .wrangler/ntfy-reverse-proxy/ that ships your config inside the worker instead of as environment variables, which Cloudflare caps at 5 KB each (about 20 contexts). The worker checks the config once when it starts instead of on every request and email.
  • Durable Object — Binds the SQLite-backed DELIVERY_OUTBOX class and declares its initial migration. This provides one logical FIFO lane per context without Cloudflare Queues, D1, or R2.
  • KV namespace — Deploy binds the namespace it found or created in step 4 (used by the Statuspage interpreter for deduplication). nrp generate leaves this binding out.

The Durable Object does not need a separate provisioning step. It is created through the generated binding and migration when Wrangler deploys the Worker. See Durable Delivery for retry behavior and cost considerations.

warning

wrangler.toml and the .wrangler/ folder are gitignored because they contain your context IDs and a copy of your config with its tokens. Do not commit them to version control.

DNS and SSL

After deployment:

  • Cloudflare automatically creates DNS records for custom domain routes. Propagation typically takes a few minutes.
  • SSL certificates are provisioned automatically by Cloudflare. This can take up to 15 minutes.
  • Your SSL/TLS mode should be set to "Full" or "Full (strict)" in the Cloudflare dashboard.

Custom Domain Routes

Routes use custom_domain = true, meaning the subdomain is the first part of the hostname. Traditional Cloudflare routes (with custom_domain = false) are not supported because the worker matches the hostname's subdomain against context IDs.

Configuring Your ntfy Servers

For the proxy to work correctly, each ntfy server should have:

  • base-url set to the server's public URL
  • behind-proxy set to true
  • attachment-cache-dir configured if you use an error topic, because the proxy sends error details as an error-debug.json attachment. Without this, ntfy cannot store uploaded files.

The proxy automatically splits messages exceeding 4000 UTF-8 bytes into numbered parts. This is handled by the proxy, not the ntfy server.

tip

ntfy's default attachment limits are: 15 MB per file (attachment-file-size-limit), 5 GB total storage (attachment-total-size-limit), and 3-hour expiry (attachment-expiry-duration). Adjust these based on your storage capacity and retention needs. Refer to the ntfy self-hosting documentation for full configuration options.