Sinatra Docs
Self-hosting

8. Expose the API publicly

Linear and GitHub need to deliver webhooks to your API. Pick a way to make it reachable.

Webhook receivers are the only inbound traffic Sinatra needs. Pick whichever option matches your setup.

Option A — Cloudflared tunnel (free, instant)

For evaluation. Random URL per run, but no domain or TLS to manage.

cloudflared tunnel --url http://localhost:8080

Note the public URL it prints. Use that as APP_BASE_URL and as the prefix for your LINEAR_REDIRECT_URI, GitHub App webhook URL, and Linear App webhook URL.

If cloudflared logs failed to dial to edge with quic: timeout and webhooks don't arrive, the network is blocking UDP. Add --protocol http2 to force HTTP/2.

Option B — ngrok (stable subdomain)

ngrok http 8080 --domain=sinatra-acme.ngrok-free.app

Free tier ngrok lets you reserve a stable subdomain — useful so you don't have to re-edit the Linear/GitHub webhook URLs every time you restart.

Option C — Named cloudflared tunnel (free, stable, requires a Cloudflare-managed domain)

If you own a domain on Cloudflare, this gives you a stable URL with no monthly cost.

cloudflared tunnel login                                       # browser → pick your zone
cloudflared tunnel create sinatra                              # creates ~/.cloudflared/<UUID>.json
cloudflared tunnel route dns sinatra sinatra.example.com       # CNAME → <UUID>.cfargotunnel.com

Create ~/.cloudflared/config.yml:

tunnel: sinatra
credentials-file: /Users/<you>/.cloudflared/<UUID>.json
protocol: http2

ingress:
  - hostname: sinatra.example.com
    service: http://localhost:8080
  - service: http_status:404

Run it:

cloudflared tunnel run sinatra

Use https://sinatra.example.com as your public API URL.

Option D — Real domain in front of your deploy (production)

Point a domain at your load balancer or Cloud Run / Cloud Functions / etc. ingress. Make sure:

  • HTTPS is terminated at the LB / ingress.
  • The path /webhooks/* reaches the API service.
  • The path /install/* reaches the API service.
  • Webhook bodies are forwarded unmodified — Sinatra verifies request signatures over the raw bytes.

Use the resulting domain as APP_BASE_URL.

What to update once you have a public URL

  1. APP_BASE_URL in your env file.
  2. LINEAR_REDIRECT_URI<APP_BASE_URL>/install/linear/callback.
  3. GitHub App webhook URL — <APP_BASE_URL>/webhooks/github.
  4. Linear App webhook URL — <APP_BASE_URL>/webhooks/linear.
  5. Linear App callback URL — <APP_BASE_URL>/install/linear/callback.
  6. GitHub App Setup URL — <APP_BASE_URL>/install/github/callback.

Continue to Configure webhooks →