Skip to main content

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.

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.

How It Works

QR Print Station reads PUBLIC_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

1

Install ngrok

Download and install the ngrok agent for your operating system from the official download page:
https://ngrok.com/download
Authenticate the agent with your ngrok account token if prompted (ngrok config add-authtoken <token>).
2

Start QR Print Station

Make sure the server is running before starting the tunnel:
.venv/bin/python server.py
The server must be listening on PORT (default 8000) for ngrok to forward traffic to it.
3

Open an ngrok tunnel in a separate terminal

ngrok http 8000
ngrok starts and displays a status line similar to:
Forwarding  https://abc123.ngrok-free.app -> http://localhost:8000
4

Copy the Forwarding URL

From the ngrok output, copy the full HTTPS Forwarding URL — for example:
https://abc123.ngrok-free.app
This is the public address customers will reach when they scan the QR code.
5

Set PUBLIC_URL in .env

Open .env and set PUBLIC_URL to the ngrok Forwarding URL:
PUBLIC_URL=https://abc123.ngrok-free.app
QR_REFRESH_SECONDS=5
Save the file. No restart of the server is needed.
6

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:
http://localhost:8000/qr.png
Opening this URL forces an immediate QR refresh (the /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

PUBLIC_URL=https://abc123.ngrok-free.app
QR_REFRESH_SECONDS=5
VariableEffect
PUBLIC_URLWhen set, get_upload_url() returns this value instead of the local IP URL. The server rewrites the QR code to point here.
QR_REFRESH_SECONDSHow 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 by start_qr_refresher() runs a tight loop:
  1. Calls get_upload_url(port), which re-reads .env on every call so it always sees the latest PUBLIC_URL.
  2. Reads the contents of qr-codes/.last_url (the URL that was last encoded into the PNG).
  3. If the two strings differ, or if qr-codes/upload.png does not exist, it calls refresh_qr(url) which writes both the PNG and the new .last_url.
  4. Sleeps for QR_REFRESH_SECONDS and repeats.
This design means you can change 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.
Free ngrok tunnels are assigned a random subdomain on every ngrok http restart. If you stop and restart ngrok, the Forwarding URL changes, and the old QR codes you have already printed will stop working. To keep a stable QR code long-term, use a paid ngrok account with a reserved domain, or use a self-hosted tunnel alternative such as Cloudflare Tunnel that provides a persistent URL.

Build docs developers (and LLMs) love