By default, QR Print Station is only reachable from devices on the same local network as the server. There are situations where a public URL is more practical: the shop’s customer Wi-Fi is isolated from the server’s network segment, you need to test the upload flow from an external device, or a staff member wants to manage orders remotely. ngrok solves all of these by creating a secure HTTPS tunnel from the public internet to your locally running server, with no firewall configuration required.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/hxmz-axfn07/qr-printing-sfw/llms.txt
Use this file to discover all available pages before exploring further.
How It Works
QR Print Station readsPUBLIC_URL from .env every time it needs to compute the customer-facing upload link. Setting PUBLIC_URL to the ngrok HTTPS URL causes get_upload_url() to return that public address instead of the local IP. A background thread runs continuously and wakes every QR_REFRESH_SECONDS seconds. On each wake it calls get_upload_url() and compares the result against the URL stored in qr-codes/.last_url. When the two values differ — or when qr-codes/upload.png does not yet exist — the thread regenerates the QR image immediately. No server restart is required; simply updating .env is enough.
Setup
Install ngrok
Download and install the ngrok agent for your operating system from the official download page:Authenticate the agent with your ngrok account token if prompted (
ngrok config add-authtoken <token>).Start QR Print Station
Make sure the server is running before starting the tunnel:The server must be listening on
PORT (default 8000) for ngrok to forward traffic to it.Copy the Forwarding URL
From the ngrok output, copy the full HTTPS Forwarding URL — for example:This is the public address customers will reach when they scan the QR code.
Set PUBLIC_URL in .env
Open Save the file. No restart of the server is needed.
.env and set PUBLIC_URL to the ngrok Forwarding URL:Wait for the QR code to regenerate
Within
QR_REFRESH_SECONDS (default 5 seconds) the background QR refresher thread detects that PUBLIC_URL has changed, calls get_upload_url() to build the new URL, writes qr-codes/upload.png with the updated QR, and saves the new URL to qr-codes/.last_url. The new QR is ready to print or display immediately.Verification
After the refresher has run, confirm the QR encodes the ngrok URL by fetching the PNG endpoint:/qr.png handler always calls refresh_qr_if_needed with force=True) and returns the current qr-codes/upload.png. Scan the returned image with a QR reader — it should decode to https://abc123.ngrok-free.app (or your actual Forwarding URL).
Environment Reference
| Variable | Effect |
|---|---|
PUBLIC_URL | When set, get_upload_url() returns this value instead of the local IP URL. The server rewrites the QR code to point here. |
QR_REFRESH_SECONDS | How often (in seconds) the background thread polls for URL changes. Lower values mean faster QR updates at the cost of slightly more I/O. Defaults to 5. |
How the QR Refresher Detects Changes
The background thread started bystart_qr_refresher() runs a tight loop:
- Calls
get_upload_url(port), which re-reads.envon every call so it always sees the latestPUBLIC_URL. - Reads the contents of
qr-codes/.last_url(the URL that was last encoded into the PNG). - If the two strings differ, or if
qr-codes/upload.pngdoes not exist, it callsrefresh_qr(url)which writes both the PNG and the new.last_url. - Sleeps for
QR_REFRESH_SECONDSand repeats.
PUBLIC_URL in .env at any time — even while the server is under load — and the QR code will silently update in the background.
PUBLIC_URL only changes what URL gets encoded into the QR code. The server itself always listens on the local PORT (default 8000). The admin dashboard remains accessible only via http://localhost:8000/admin/<ADMIN_TOKEN> or the local IP — it is never exposed through the PUBLIC_URL redirect.