Notifications
Nginx (HTTPS)

Nginx (HTTPS Reverse Proxy)

For iOS reliability (especially notification images), it helps to expose Frigate snapshots over HTTPS with a trusted certificate.

Nginx is a common reverse-proxy choice:

  • Your phone connects to https://nvr.example.com
  • Nginx forwards to Frigate on your LAN (e.g., http://127.0.0.1:5000)

If you use Cloudflare Tunnel, you can either:

  • Tunnel directly to Frigate (no Nginx required), or
  • Tunnel to Nginx and let Nginx proxy internally (useful when you already have Nginx in front of multiple services)

Quick start (minimal, reliable approach)

  1. Point DNS for nvr.example.com at the machine running Nginx (or tunnel traffic there)
  2. Configure Nginx to proxy to Frigate
  3. Issue a trusted certificate (Let’s Encrypt is common)
  4. Validate https://nvr.example.com/api/version from a laptop and from your phone

If any step fails, do not move forward until it is fixed. Proxy chains amplify small mistakes.

Step 0: Install Nginx (Debian/Ubuntu)

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx --no-pager

Step 1: Create a site config

Create: /etc/nginx/sites-available/frigate

Example (replace nvr.example.com and upstream host/port):

server {
    listen 80;
    server_name nvr.example.com;
 
    # Redirect all HTTP to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}
 
server {
    listen 443 ssl;
    server_name nvr.example.com;
 
    ssl_certificate     /etc/letsencrypt/live/nvr.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/nvr.example.com/privkey.pem;
 
    location / {
        proxy_pass http://127.0.0.1:5000;
 
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
        # WebSockets (helps for some live-view stacks)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Enable it:

sudo ln -s /etc/nginx/sites-available/frigate /etc/nginx/sites-enabled/frigate
sudo nginx -t
sudo systemctl reload nginx

Step 2: Get a certificate (Let’s Encrypt)

Follow: Let’s Encrypt

Tip: For iOS, the big win here is “trusted TLS.” A self-signed certificate can work for some browsing, but notification images (and some streaming paths) are far more likely to fail.

Step 3: Verify (from laptop and phone)

From your laptop:

curl -i https://nvr.example.com/api/version

You should see 200 and version JSON.

Then open https://nvr.example.com on your phone (Safari) and confirm it loads quickly and without certificate warnings.

Step 4 (optional): If you use Cloudflare Access

If you put Cloudflare Access in front of nvr.example.com, Viewu must send the Service Token headers:

  • CF-Access-Client-Id
  • CF-Access-Client-Secret

Guide: Cloudflare Tunnels

Troubleshooting (symptom → likely cause → fix)

502 / 504 from Nginx

Likely cause: Frigate isn’t reachable at the upstream address.

Fix: verify upstream directly from the Nginx machine:

curl -i http://127.0.0.1:5000/api/version

If Frigate is on another machine/container, update proxy_pass to the correct reachable address.

iOS can load pages but notifications show no images

Likely causes:

  • The snapshot URL is only reachable on a private IP (VPN required, but phone is not connected)
  • The cert is not trusted or does not match the hostname
  • Cloudflare Access is enabled but the request is missing headers

Fixes:

  • Prefer https://nvr.example.com with trusted TLS
  • If using VPN, ensure the phone is connected at notification time
  • If using Cloudflare Access, confirm Viewu has the correct Client ID/Secret set

“It works on Wi‑Fi but fails on cellular”

Likely cause: DNS/routing differs off-LAN.

Fix: test the exact URL on cellular in Safari. If Safari can’t load it, Viewu cannot either.

Last updated on December 17, 2025