Postwright

Public media URL

Optional, and only for Instagram Reels. Most installs should leave it off. Without it, Postwright uploads each Reel to Meta itself and nothing on your Mac is reachable from the internet.

When you need it

Meta can take in a Reel two ways:

  1. Upload (the default). Postwright sends the video file to Meta. No public address needed.
  2. Fetch by link. Postwright gives Meta a link and Meta downloads the file. Some large or unusual videos get through this way when an upload is rejected with a vague “processing failed”.

Fetching by link needs a public https address that serves the video. This page sets one up with a Cloudflare Tunnel, restricted so that only the Reel files you’ve just posted can be reached.

With a public URL set, Postwright tries the link first and falls back to the upload if Meta can’t fetch it. Either way, the Reel is published once. If Meta doesn’t fetch a link within 90 seconds, that Reel uploads instead and the link is skipped for the next hour, so a broken tunnel doesn’t slow down every Reel.

How the link is protected

  • Each link names one file through a signed token, not a path. There is no directory listing.
  • A link expires after one hour, is tied to the file’s size, and is signed with a secret generated for your install.
  • A link can only point inside the phone-shorts work folder or the video watch folder. Anything that tries to leave those folders is refused.
  • Responses aren’t cached by the tunnel.

Set it up

You need a domain on Cloudflare and cloudflared installed. The examples use media.example.com; use your own.

1. Create the tunnel and its DNS name

cloudflared tunnel login
cloudflared tunnel create postwright
cloudflared tunnel route dns postwright media.example.com

2. Point it at Postwright, Reel files only

In ~/.cloudflared/postwright.yml:

tunnel: postwright
credentials-file: /Users/you/.cloudflared/<tunnel-id>.json

ingress:
  - hostname: media.example.com
    path: ^/api/media/reel/.+
    service: http://127.0.0.1:8002
  - service: http_status:404
Don’t skip the path line. Postwright’s port also serves your dashboard and its API. The path rule forwards only the Reel files. Everything else gets a 404 from cloudflared and never reaches Postwright. A tunnel without it puts your login page and API on the internet.

On Pro, if your brand sites also call this server through the same tunnel (to subscribe, confirm, manage preferences, or unsubscribe), add just those endpoints to the same rule instead of opening the whole host, for example ^/api/(media/reel/.+|subscribe|subscribers/.+|confirm|preferences|unsubscribe).

3. Check the rule before you rely on it

cloudflared tunnel ingress rule https://media.example.com/api/media/reel/x/reel.mp4
# should match the media rule

cloudflared tunnel ingress rule https://media.example.com/
# must report the catch-all (http_status:404)

Then try it from outside: https://media.example.com/ and https://media.example.com/api/health must both return 404.

4. Run the tunnel

cloudflared tunnel --config ~/.cloudflared/postwright.yml run postwright

5. Tell Postwright the address

In Connections > Public media URL (or the phone-shorts step of the setup wizard), enter https://media.example.com, the address only with no path. Save, then restart Postwright. Leaving it empty turns this off.

Publishing stays local-only

Every dashboard route needs a login, and the routes that publish or spend money also refuse any request that arrives through a tunnel. A local reverse proxy on the same Mac still works. Treat the path rule above as required anyway.

Troubleshooting

  • The log says the Reel fell back to upload. Meta couldn’t fetch the link: the tunnel is down, the rule is too narrow, or the file moved. The Reel still posts by upload.
  • The log says the public media URL was ignored. The saved address isn’t a public https address. Fix it in Connections.
  • https://media.example.com/ shows a page. The path rule is missing. Fix the tunnel config before anything else.

Back to Phone shorts or the Instagram connection.