Skip to content

Reverse Proxy and HTTPS

thenotoriousJeremy edited this page Aug 20, 2026 · 2 revisions

Reverse Proxy & HTTPS Configuration

To use the camera scanner from a mobile phone or remote device, HTTPS is strictly required. Web browsers enforce the W3C Secure Contexts specification, which disables navigator.mediaDevices.getUserMedia (camera and microphone access) on insecure http:// connections to anything other than localhost.


Architecture Overview

When deploying with a reverse proxy:

  1. The reverse proxy terminates TLS (using Let's Encrypt or your custom certificates) on port 443.
  2. The proxy forwards unencrypted traffic to Bindarr's HTTP port 3001.
  3. Bindarr's native HTTPS port 3443 is disabled or left unpublished.
  4. Set TRUST_PROXY=1 so Bindarr's rate limiting and security middleware accurately read the client's real IP address from the X-Forwarded-For header.
Client (Phone Browser) ──[ HTTPS :443 ]──▶ Reverse Proxy (Caddy/Nginx) ──[ HTTP :3001 ]──▶ Bindarr Container

Essential Environment Variables

When running behind any reverse proxy, set these environment variables in your docker-compose.yml or .env:

environment:
  - TRUST_PROXY=1
  - PUBLIC_BASE_URL=https://cards.yourdomain.com
  - CORS_ORIGIN=https://cards.yourdomain.com
  • TRUST_PROXY=1: Instructs Express to trust the single reverse proxy hop. Prevents rate-limiter IP spoofing.
  • PUBLIC_BASE_URL: Sets the canonical public URL used when generating shareable links for your collection.
  • CORS_ORIGIN: Permits cross-origin requests from your custom domain.

Configuration Examples

1. Caddy (Recommended)

Caddy handles automatic HTTPS provisioning and certificate renewal out of the box.

Add this to your Caddyfile:

cards.yourdomain.com {
    reverse_proxy localhost:3001
}

If Caddy is running in a Docker container alongside Bindarr on the same Docker network:

cards.yourdomain.com {
    reverse_proxy bindarr:3001
}

2. Nginx Proxy Manager (NPM)

  1. Open your Nginx Proxy Manager dashboard.
  2. Click Proxy Hosts → Add Proxy Host.
  3. Details Tab:
    • Domain Names: cards.yourdomain.com
    • Scheme: http
    • Forward Hostname / IP: bindarr (if on same Docker network) or 192.168.1.X
    • Forward Port: 3001
    • Block Common Exploits: Enabled
    • Websockets Support: Enabled
  4. SSL Tab:
    • SSL Certificate: Request a new Let's Encrypt Certificate
    • Force SSL: Enabled
    • HTTP/2 Support: Enabled
    • HSTS Enabled: Enabled

3. Nginx (Standard Config)

Create /etc/nginx/sites-available/bindarr.conf:

server {
    listen 80;
    server_name cards.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name cards.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/cards.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/cards.yourdomain.com/privkey.pem;

    # Allow card image uploads and large JSON imports
    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;

        proxy_set_header Host $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 support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

4. Traefik (Docker Compose Labels)

If using Traefik as your edge router:

services:
  bindarr:
    image: ghcr.io/thenotoriousjeremy/bindarr:latest
    container_name: bindarr
    restart: unless-stopped
    environment:
      - TRUST_PROXY=1
      - PUBLIC_BASE_URL=https://cards.yourdomain.com
    volumes:
      - bindarr-data:/app/database
    networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bindarr.rule=Host(`cards.yourdomain.com`)"
      - "traefik.http.routers.bindarr.entrypoints=websecure"
      - "traefik.http.routers.bindarr.tls.certresolver=letsencrypt"
      - "traefik.http.services.bindarr.loadbalancer.server.port=3001"

networks:
  web:
    external: true

5. Tailscale Serve / Funnel

If you use Tailscale, you can route secure HTTPS directly to your machine without opening router ports:

# Serve over HTTPS to devices on your private Tailnet:
tailscale serve https / http://127.0.0.1:3001

Tailscale automatically provides a trusted HTTPS certificate for your *.ts.net domain, allowing phone cameras to scan without any browser warnings.


Direct LAN Access Without a Proxy

If you don't run a reverse proxy and want to access Bindarr on your local home network (e.g. https://192.168.1.50:3443), Bindarr will automatically generate a self-signed TLS certificate on first start:

  1. In your browser, navigate to https://192.168.1.50:3443.
  2. Your browser will warn that the certificate authority is unknown.
  3. Click Advanced → Proceed to 192.168.1.50 (unsafe) (on iOS Safari: Show Details → Visit this website).
  4. Once accepted on each mobile device, the camera will work properly.

Clone this wiki locally